home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / SNNSV32.ZIP / SNNSv3.2 / kernel / sources / init_f.c < prev    next >
C/C++ Source or Header  |  1994-04-25  |  73KB  |  2,466 lines

  1. /*****************************************************************************
  2.   FILE           : init_f.c
  3.   SHORTNAME      : 
  4.   SNNS VERSION   : 3.2
  5.  
  6.   PURPOSE        : SNNS-Kernel Network Initialisation Functions
  7.   NOTES          :
  8.  
  9.   AUTHOR         : Niels Mache
  10.   DATE           : 18.03.91
  11.  
  12.   CHANGED BY     : Sven Doering, Ralf Huebner, Marc Seemann (Uni Tuebingen)
  13.   IDENTIFICATION : @(#)init_f.c    1.28 4/15/94
  14.   SCCS VERSION   : 1.28
  15.   LAST CHANGE    : 4/15/94
  16.  
  17.              Copyright (c) 1990-1994  SNNS Group, IPVR, Univ. Stuttgart, FRG
  18.  
  19. ******************************************************************************/
  20. #include <math.h>
  21. #include <stdio.h>
  22.  
  23. #include "kr_typ.h"     /*  Kernel Types and Constants             */
  24. #include "kr_const.h"     /*  Constant Declarators for SNNS-Kernel   */
  25. #include "kr_def.h"     /*  Default Values                         */
  26. #include "kernel.h"     /*  SNNS-Kernel Function Prototypes        */
  27. #include "glob_typ.h"    /*  Global Types                           */
  28. #include "kr_mac.h"      /*  Macros                                 */
  29. #include "random.h"     /*  Randomize Library Function Prototypes  */
  30. #include "kr_mac.h"     /*  Kernel Macros                          */
  31. #include "kr_art.h"      /*  Prototypes and global defs for ART     */
  32. #include "kr_art1.h"     /*  Prototypes and global defs for ART1    */
  33. #include "kr_art2.h"     /*  Prototypes and global defs for ART2    */
  34. #include "kr_amap.h"     /*  Prototypes and global defs for ARTMAP  */
  35. #include "krart_df.h"    /*  Definitions for ART functions          */
  36. #include "kr_ui.h"
  37. #include "cc_rcc.h"      /* Definitions for cascade                 */
  38. #include "matrix.h"
  39. #include "kr_newpattern.h"
  40.  
  41. #include "init_f.ph"
  42.  
  43.  
  44.  
  45. /*****************************************************************************
  46.   FUNCTION : INIT_randomizeWeights
  47.  
  48.   PURPOSE  : Initializes connection weights with uniform distributed 
  49.              random values.
  50.   RETURNS  : 
  51.   NOTES    : Function calls drand48(). <min> must be less then <max>.
  52.  
  53.   UPDATE   : 05.04.94 by Sven Doering
  54. ******************************************************************************/
  55. krui_err  INIT_randomizeWeights(float *parameterArray, int NoOfParams)
  56. {
  57.     register unsigned short    flags;
  58.     register struct Link   *link_ptr;
  59.     register struct Site   *site_ptr;
  60.     register struct Unit   *unit_ptr;
  61.     register FlintType     range, min_weight;
  62.     FlintType   max_weight;
  63.  
  64.     if ( (unit_array == NULL) || (NoOfUnits == 0) )
  65.     return( KRERR_NO_UNITS ); /*  there is nothing to do  */
  66.  
  67.     min_weight = INIT_PARAM1( parameterArray );
  68.     max_weight = INIT_PARAM2( parameterArray ); 
  69.     range = max_weight - min_weight;
  70.  
  71.     if (range == 0.0)  {
  72.     FOR_ALL_UNITS( unit_ptr )  {
  73.         flags = unit_ptr->flags;
  74.  
  75.         if ( ((flags & UFLAG_IN_USE) == UFLAG_IN_USE) 
  76.         && (!IS_SPECIAL_UNIT(unit_ptr))) {
  77.         /*  unit is in use  */
  78.         unit_ptr->bias = min_weight;
  79.  
  80.         if ( (flags & UFLAG_INPUT_PAT) == UFLAG_SITES ) {
  81.             /*  unit has sites  */
  82.             FOR_ALL_SITES_AND_LINKS( unit_ptr, site_ptr, link_ptr )
  83.             link_ptr->weight = min_weight;
  84.         }else{
  85.             /*  unit has no sites   */
  86.             if ( (flags & UFLAG_INPUT_PAT) == UFLAG_DLINKS ) {
  87.             /*  unit has direct links   */
  88.             FOR_ALL_LINKS( unit_ptr, link_ptr )
  89.                 link_ptr->weight = min_weight;
  90.             }
  91.         }
  92.         }
  93.     }
  94.     } else  {
  95.     FOR_ALL_UNITS( unit_ptr )  {
  96.         flags = unit_ptr->flags;
  97.  
  98.         if ( ((flags & UFLAG_IN_USE) == UFLAG_IN_USE)
  99.         && (!IS_SPECIAL_UNIT(unit_ptr))) {
  100.         /*  unit is in use  */
  101.         unit_ptr->bias = (FlintType) drand48() * range + min_weight;
  102.  
  103.         if ( (flags & UFLAG_INPUT_PAT) == UFLAG_SITES ) {
  104.             /*  unit has sites  */
  105.             FOR_ALL_SITES_AND_LINKS( unit_ptr, site_ptr, link_ptr )
  106.             link_ptr->weight = 
  107.                 (FlintType)drand48() * range + min_weight;
  108.         } else  {
  109.             /*  unit has no sites   */
  110.             if ( (flags & UFLAG_INPUT_PAT) == UFLAG_DLINKS ){
  111.             /*  unit has direct links   */
  112.             FOR_ALL_LINKS( unit_ptr, link_ptr )
  113.                 link_ptr->weight = 
  114.                 (FlintType) drand48() * range + min_weight;
  115.             }
  116.         }
  117.         }
  118.     }
  119.     }
  120.  
  121.     return( KRERR_NO_ERROR );
  122. }
  123.  
  124.  
  125.  
  126. /*****************************************************************************
  127.   FUNCTION : INIT_RM_randomizeWeights
  128.  
  129.   PURPOSE  : Initializes connection weights between hidden units with uniform 
  130.              distributed random values. Connections from input units are not 
  131.          changed. This kind of initialization is necessary for 
  132.          autoassociative memory networks.
  133.   RETURNS  : 
  134.   NOTES    : Function calls drand48(). <min> must be less then <max>.
  135.  
  136.   UPDATE   : 11.02.94
  137. ******************************************************************************/
  138. krui_err  INIT_RM_randomizeWeights(float *parameterArray, int NoOfParams)
  139. {
  140.   register unsigned short    flags;
  141.   register struct Link   *link_ptr;
  142.   register struct Site   *site_ptr;
  143.   register struct Unit   *unit_ptr;
  144.   register FlintType     range, min_weight;
  145.   FlintType   max_weight;
  146.  
  147.   if ( (unit_array == NULL) || (NoOfUnits == 0) )
  148.     return( KRERR_NO_UNITS );  /*  there is nothing to do  */
  149.  
  150.   min_weight = INIT_PARAM1( parameterArray );
  151.   max_weight = INIT_PARAM2( parameterArray ); 
  152.   range = max_weight - min_weight;
  153.  
  154.   if (range == 0.0)  {
  155.     FOR_ALL_UNITS( unit_ptr )  {
  156.       flags = unit_ptr->flags;
  157.  
  158.       if ( ((flags & UFLAG_IN_USE) == UFLAG_IN_USE)
  159.       && (!IS_SPECIAL_UNIT(unit_ptr)))
  160.         {  /*  unit is in use  */
  161.         unit_ptr->bias = min_weight;
  162.  
  163.         if ( (flags & UFLAG_INPUT_PAT) == UFLAG_SITES )
  164.           {  /*  unit has sites  */
  165.       FOR_ALL_SITES_AND_LINKS( unit_ptr, site_ptr, link_ptr )
  166.             if (!IS_INPUT_UNIT (link_ptr->to))
  167.               link_ptr->weight = min_weight;
  168.         }else
  169.           {       /*  unit has no sites   */
  170.           if ( (flags & UFLAG_INPUT_PAT) == UFLAG_DLINKS )
  171.             {     /*  unit has direct links   */
  172.         FOR_ALL_LINKS( unit_ptr, link_ptr )
  173.               if (!IS_INPUT_UNIT (link_ptr->to))
  174.               link_ptr->weight = min_weight;
  175.           }
  176.         }
  177.       }
  178.     }
  179.   }else  {
  180.     FOR_ALL_UNITS( unit_ptr )  {
  181.       flags = unit_ptr->flags;
  182.  
  183.       if ( ((flags & UFLAG_IN_USE) == UFLAG_IN_USE)
  184.       && (!IS_SPECIAL_UNIT(unit_ptr)))
  185.         {     /*  unit is in use  */
  186.         unit_ptr->bias = (FlintType) drand48() * range + min_weight;
  187.  
  188.         if ( (flags & UFLAG_INPUT_PAT) == UFLAG_SITES )
  189.           {       /*  unit has sites  */
  190.       FOR_ALL_SITES_AND_LINKS( unit_ptr, site_ptr, link_ptr )
  191.             if (!IS_INPUT_UNIT (link_ptr->to))
  192.             link_ptr->weight = (FlintType) drand48() * range + min_weight;
  193.         }else  {
  194.           /*  unit has no sites   */
  195.           if ( (flags & UFLAG_INPUT_PAT) == UFLAG_DLINKS )
  196.             {     /*  unit has direct links   */
  197.         FOR_ALL_LINKS( unit_ptr, link_ptr )
  198.               if (!IS_INPUT_UNIT (link_ptr->to))
  199.               link_ptr->weight = (FlintType) drand48() * range + min_weight;
  200.           }
  201.         }
  202.       }
  203.     }
  204.   }
  205.  
  206.   return( KRERR_NO_ERROR );
  207. }
  208.  
  209.  
  210.  
  211.  
  212. /*****************************************************************************
  213.   FUNCTION : INIT_randomizeWeights_perc
  214.  
  215.   PURPOSE  :
  216.   RETURNS  : 
  217.   NOTES    :
  218.  
  219.   UPDATE   : 
  220. ******************************************************************************/
  221. krui_err  INIT_randomizeWeights_perc(float *parameterArray, int NoOfParams)
  222. {
  223.     register unsigned short    flags;
  224.     register struct Link   *link_ptr;
  225.     register struct Site   *site_ptr;
  226.     register struct Unit   *unit_ptr;
  227.     register FlintType     range, min_weight;
  228.     FlintType              max_weight;
  229.     FlintType              ar;
  230.  
  231.     if ( (unit_array == NULL) || (NoOfUnits == 0) )
  232.     return( KRERR_NO_UNITS ); /*  there is nothing to do  */
  233.  
  234.     min_weight = INIT_PARAM1( parameterArray );
  235.     max_weight = INIT_PARAM2( parameterArray );
  236.     range = max_weight - min_weight;
  237.  
  238.     /*Anzahl der Vorgaengerunits werden bestimmt*/
  239.     FOR_ALL_UNITS( unit_ptr ){
  240.     unit_ptr->value_c=0.0;
  241.     FOR_ALL_LINKS( unit_ptr, link_ptr ){
  242.         unit_ptr->value_c++;
  243.     }
  244.     }
  245.  
  246.  
  247.     if (range == 0.0)  {
  248.     FOR_ALL_UNITS( unit_ptr )  {
  249.         flags = unit_ptr->flags;
  250.  
  251.         if ( ((flags & UFLAG_IN_USE) == UFLAG_IN_USE) 
  252.         && (!IS_SPECIAL_UNIT(unit_ptr))) {
  253.         /*  unit is in use  */
  254.         unit_ptr->bias = min_weight;
  255.  
  256.         if ( (flags & UFLAG_INPUT_PAT) == UFLAG_SITES ){
  257.             /*  unit has sites  */
  258.             FOR_ALL_SITES_AND_LINKS( unit_ptr, site_ptr, link_ptr )
  259.             link_ptr->weight = min_weight;
  260.         } else  {
  261.             /*  unit has no sites   */
  262.             if ( (flags & UFLAG_INPUT_PAT) == UFLAG_DLINKS ) {
  263.             /*  unit has direct links   */
  264.             FOR_ALL_LINKS( unit_ptr, link_ptr )
  265.                 link_ptr->weight = min_weight;
  266.             }
  267.         }
  268.         }
  269.     }
  270.     } else  {
  271.     FOR_ALL_UNITS( unit_ptr )  {
  272.         flags = unit_ptr->flags;
  273.  
  274.         if ( ((flags & UFLAG_IN_USE) == UFLAG_IN_USE) 
  275.         && (!IS_SPECIAL_UNIT(unit_ptr))) {
  276.         /*  unit is in use  */
  277.         unit_ptr->bias = 0.0;
  278.  
  279.         if ( (flags & UFLAG_INPUT_PAT) == UFLAG_SITES ){
  280.             /*  unit has sites  */
  281.             FOR_ALL_SITES_AND_LINKS( unit_ptr, site_ptr, link_ptr ){
  282.             ar = unit_ptr->value_c ;
  283.             link_ptr->weight = 
  284.                 (FlintType) drand48() * 
  285.                 (max_weight/ar - min_weight/ar) + (min_weight/ar);
  286.             }
  287.         } else  {
  288.             /*  unit has no sites   */
  289.             if ( (flags & UFLAG_INPUT_PAT) == UFLAG_DLINKS ){
  290.             /*  unit has direct links   */
  291.  
  292.             FOR_ALL_LINKS( unit_ptr, link_ptr ) {
  293.                 ar = unit_ptr->value_c ;
  294.                 link_ptr->weight = 
  295.                 (FlintType) drand48() * 
  296.                 (max_weight/ar - min_weight/ar) + 
  297.                 (min_weight/ar);
  298.             }
  299.             }
  300.         }
  301.         }
  302.     }
  303.     }
  304.     return( KRERR_NO_ERROR );
  305. }
  306.  
  307.  
  308.  
  309. /*****************************************************************************
  310.   FUNCTION : INIT_Weights_CPN
  311.  
  312.   PURPOSE  :
  313.   RETURNS  : 
  314.   NOTES    :
  315.  
  316.   UPDATE   : 
  317. ******************************************************************************/
  318. krui_err INIT_Weights_CPN(float *parameterArray, int NoOfParams)
  319. {
  320.     register struct Unit *unit_ptr;
  321.     register struct Site *site_ptr;
  322.     register struct Link *link_ptr;
  323.     register TopoPtrArray  topo_ptr;
  324.     register FlintType  sum, amount, range;
  325.     FlintType min, max;
  326.     int  ret_code;
  327.  
  328.  
  329.     if ( (unit_array == NULL) || (NoOfUnits == 0) )
  330.     return( KRERR_NO_UNITS ); /*  there is nothing to do  */
  331.  
  332.     min = INIT_PARAM1( parameterArray );
  333.     max = INIT_PARAM2( parameterArray );
  334.     range = max - min;
  335.  
  336.     if (NetModified || (TopoSortID != TOPOLOGIC_TYPE)){
  337.     /*  networt was modified or topologic array isn't initialized  */
  338.     ret_code = kr_topoSort( TOPOLOGIC_TYPE );
  339.     if (ret_code != KRERR_NO_ERROR)
  340.         return( ret_code );
  341.  
  342.     NetModified = FALSE;
  343.     }
  344.  
  345.     topo_ptr = topo_ptr_array + (NoOfInputUnits + 1);
  346.  
  347.     /*  initialize weights of the hidden units  */
  348.     while ((unit_ptr = *++topo_ptr) != NULL){
  349.     /*  this is a hidden unit  */
  350.  
  351.     /*     initialize the weights to the Kohonen Layer         */
  352.     sum = 0.0;
  353.     if UNIT_HAS_SITES( unit_ptr ){
  354.         /* the unit has sites */
  355.         FOR_ALL_SITES_AND_LINKS( unit_ptr, site_ptr, link_ptr )  {
  356.         link_ptr->weight = (FlintType) drand48() * range + min;
  357.         sum += link_ptr->weight * link_ptr->weight;
  358.         }
  359.     }else{
  360.         /* the unit has direct links */
  361.         FOR_ALL_LINKS( unit_ptr, link_ptr )  {
  362.         link_ptr->weight = (FlintType) drand48() * range + min;
  363.         sum += link_ptr->weight * link_ptr->weight;
  364.         }
  365.     }
  366.  
  367.     /* normalize the weightvector to the Kohonen Layer */
  368.     amount = 1.0 / sqrt( sum );
  369.  
  370.     if UNIT_HAS_SITES( unit_ptr )
  371.         /* the unit has sites */
  372.         FOR_ALL_SITES_AND_LINKS( unit_ptr, site_ptr, link_ptr )
  373.         link_ptr->weight = link_ptr->weight * amount;
  374.     else
  375.         /* the unit has direct links */
  376.         FOR_ALL_LINKS( unit_ptr, link_ptr )
  377.         link_ptr->weight = link_ptr->weight * amount;
  378.     }
  379.  
  380.  
  381.     while ((unit_ptr = *++topo_ptr) != NULL){
  382.     /* this is a output unit */
  383.  
  384.     /*     initialize the weights to the Grossberg Layer       */
  385.     if UNIT_HAS_SITES( unit_ptr ){
  386.         /* the unit has sites */
  387.         FOR_ALL_SITES_AND_LINKS( unit_ptr, site_ptr, link_ptr )
  388.         link_ptr->weight = (FlintType) drand48() * range + min;
  389.     }else{
  390.         /* the unit has direct links */
  391.         FOR_ALL_LINKS( unit_ptr, link_ptr )
  392.         link_ptr->weight = (FlintType) drand48() * range + min;
  393.     }
  394.     }
  395.  
  396.     return( KRERR_NO_ERROR );
  397. }
  398.  
  399.  
  400.  
  401. /*****************************************************************************
  402.   FUNCTION : RbfInitSetCenter
  403.  
  404.   PURPOSE  :
  405.   RETURNS  : 
  406.   NOTES    : The pattern is loaded into the input layer and propagated to the 
  407.              output of the INPUT layer. After that, the weights of the links 
  408.          leading to the <hidden_unit> are set to the output values of the 
  409.          corresponding input units. (A center of a RBF is set).
  410.          The value of <deviation> is used for symmetry breaking: it gives 
  411.          the percentage of the maximum random change of the input pattern. 
  412.          deviation 1.0 means 100% which means that an input value of x will
  413.          lead to a stored weight between 0.0 and 2*x. A value of 0.0 will 
  414.          not change the weights!
  415.          The bias of the <hidden_unit> is set to 1.0 (parameter of the RBF)
  416.  
  417.   UPDATE   : 
  418. ******************************************************************************/
  419. void RbfInitSetCenter(int pattern_no, int sub_pat_no, 
  420.               struct Unit *hidden_unit, float deviation, float bias)
  421. {
  422.     register struct Unit    *unit_ptr;
  423.     register struct Link    *link_ptr;
  424.     register Patterns    current_in_pattern;
  425.     register TopoPtrArray    topo_ptr;
  426.  
  427.     /* calculate index of the input pattern in Pattern array:    */
  428.     current_in_pattern = kr_getSubPatData(pattern_no,sub_pat_no,INPUT,NULL);
  429.  
  430.     /* activate input units with the pattern and calculate the output value */
  431.     topo_ptr = topo_ptr_array;
  432.     while ((unit_ptr = *(++topo_ptr)) != NULL){
  433.  
  434.     /* go through all input units, set activation and calculate output: */
  435.     unit_ptr -> act = *current_in_pattern++;
  436.     unit_ptr -> Out.output = unit_ptr -> out_func == OUT_IDENTITY 
  437.         ? unit_ptr -> act : (*unit_ptr -> out_func) (unit_ptr -> act);
  438.     }
  439.  
  440.     /* set the weights of the links: */
  441.     if (deviation == 0.0){
  442.     FOR_ALL_LINKS(hidden_unit, link_ptr){
  443.         link_ptr -> weight = link_ptr -> to -> Out.output;
  444.     }
  445.     }else{
  446.     deviation /= 6.3137515;
  447.     FOR_ALL_LINKS(hidden_unit, link_ptr){
  448.         link_ptr->weight = link_ptr->to->Out.output *
  449.         (1.0 + deviation * 
  450.          tan(((float)drand48() * 2.8274334 - 1.4137167)));
  451.     }
  452.     }
  453.  
  454.     hidden_unit->bias = bias;
  455. }
  456.  
  457.  
  458.  
  459. /*****************************************************************************
  460.   FUNCTION : RbfInitBPCenter 
  461.  
  462.   PURPOSE  :
  463.   RETURNS  : 
  464.   NOTES    : The weights of the links leading to the <hidden_unit> are 
  465.              propagated back to the Output value of the corresponding input 
  466.          units. Only the Out.output of the input units is set. The 
  467.          activation remains unchanged.
  468.  
  469.   UPDATE   : 
  470. ******************************************************************************/
  471. void RbfInitBPCenter(struct Unit *hidden_unit)
  472. {
  473.     register struct Link    *curr_link;
  474.  
  475.     FOR_ALL_LINKS(hidden_unit, curr_link){
  476.     curr_link -> to -> Out.output = curr_link -> weight;
  477.     }
  478. }
  479.  
  480.  
  481.  
  482. /*****************************************************************************
  483.   FUNCTION : RbfInitNetwork
  484.  
  485.   PURPOSE  : Initialization Function for Use of Radial Basis Functions
  486.   RETURNS  : 
  487.   NOTES    : First initialization of centers and direct calculation of all 
  488.              weights as first step during learning.
  489.          The initialization of a center consists of setting the 
  490.          coordinates of the center (the weights of the links, leading to 
  491.          it) and setting the RBF function parameter (bias of the unit) to 
  492.          i_bias.
  493.  
  494.   UPDATE   : 
  495. ******************************************************************************/
  496. krui_err  RbfInitNetwork(int start_pat, int end_pat, float i_bias, 
  497.              float i_devi, float i_f_0, float i_f_1, 
  498.              float i_smooth, int init_type)
  499. {
  500.     register struct Unit    *unit_ptr;
  501.     register struct Unit    *h_unit_ptr;
  502.     register struct Link    *link_ptr;
  503.     register Patterns       current_out_pattern;
  504.     register TopoPtrArray   topo_ptr;
  505.     register TopoPtrArray   topo_hidden_ptr;
  506.     register TopoPtrArray   topo_work;
  507.     register int        hidden_units;
  508.     register int        output_units;
  509.     register int        unit_nr;
  510.     register int        h_unit_nr;
  511.     register int        abs_sub_nr;
  512.     register int        pattern_anz;
  513.     int                        pattern_no;
  514.     int                     sub_pat_no;
  515.     register float        deviation;
  516.     register int        abort;
  517.     register int        tmp_err;
  518.     register int            start_sp;
  519.     register int            end_sp;
  520.  
  521.     RbfFloatMatrix        hidden_act;
  522.     RbfFloatMatrix        t_hidden_act;
  523.     RbfFloatMatrix        hidden_produkt;
  524.     RbfFloatMatrix        inter_act;
  525.     RbfFloatMatrix        hidden_sum;
  526.     RbfFloatMatrix        m_p_inverse;
  527.     RbfFloatMatrix        y_vektor;
  528.     RbfFloatMatrix        weights_vektor;
  529. #ifdef RBF_MATRIX_TEST
  530.     RbfFloatMatrix        alt_hidden_sum;
  531.     RbfFloatMatrix        soll_einheit_sein;
  532.     int                s,z;
  533. #endif
  534.     int                malloc_fault;
  535.  
  536.  
  537.     abort = FALSE;
  538.  
  539.     if (init_type == RBF_INIT_FULL){
  540.     fprintf(stderr,"RBF_Weights called, start initialization:\n");
  541.     }else{
  542.     fprintf(stderr,"RBF_Weights_Redo called, start initialization:\n");
  543.     }
  544.     
  545.     fprintf(stderr, "... preparing initialization\n");
  546.  
  547.     /* count the units of the hidden layer (only one) and the output layer */
  548.     hidden_units = 0;
  549.     output_units = 0;
  550.     FOR_ALL_UNITS(unit_ptr){
  551.     if ((unit_ptr -> flags & UFLAG_IN_USE) == UFLAG_IN_USE) {
  552.         if (unit_ptr -> flags & UFLAG_TTYP_HIDD)
  553.         hidden_units++;
  554.         if (unit_ptr -> flags & UFLAG_TTYP_OUT)
  555.         output_units++; 
  556.     }
  557.     }
  558.  
  559.     /* set <unit_ptr> to the NULL between first hidden and last input unit: */
  560.     topo_ptr = topo_ptr_array;
  561.     while ((unit_ptr = *(++topo_ptr)) != NULL);    /* empty loop!    */
  562.  
  563.     /* reference to first hidden unit */
  564.     topo_hidden_ptr = topo_ptr;
  565.     topo_hidden_ptr++;
  566.  
  567.     /* compute the necessary sub patterns */
  568.     KernelErrorCode = kr_initSubPatternOrder(start_pat,end_pat);
  569.     if(KernelErrorCode != KRERR_NO_ERROR) return (KernelErrorCode);
  570.     start_sp = kr_AbsPosOfFirstSubPat(start_pat);
  571.     end_sp = kr_AbsPosOfFirstSubPat(end_pat) + kr_NoOfSubPatPairs(end_pat) - 1;
  572.     pattern_anz = end_sp - start_sp + 1;
  573.  
  574.     /* Output bias is treated as additional hidden unit    */
  575.     hidden_units += 1;
  576.  
  577.     /* Allocate memory for all matrixes: */
  578.     malloc_fault = 0;
  579.     if (!RbfAllocMatrix(pattern_anz, hidden_units, &hidden_act))
  580.     malloc_fault = 0;
  581.     else if (!RbfAllocMatrix(hidden_units, pattern_anz, &t_hidden_act))
  582.     malloc_fault = 1;
  583.     else if (!RbfAllocMatrix(hidden_units, hidden_units, &hidden_produkt))
  584.     malloc_fault = 2;
  585.     else if (!RbfAllocMatrix(hidden_units, hidden_units, &inter_act))
  586.     malloc_fault = 3;
  587.     else if (!RbfAllocMatrix(hidden_units, hidden_units, &hidden_sum))
  588.     malloc_fault = 4;
  589.     else if (!RbfAllocMatrix(pattern_anz, 1, &y_vektor))
  590.     malloc_fault = 5;
  591.     else if (!RbfAllocMatrix(hidden_units, 1, &weights_vektor))
  592.     malloc_fault = 6;
  593.     else if (!RbfAllocMatrix(hidden_units, pattern_anz, &m_p_inverse))
  594.     malloc_fault = 7;
  595. #ifdef RBF_MATRIX_TEST
  596.     else if (!RbfAllocMatrix(hidden_units, hidden_units, &alt_hidden_sum))
  597.     malloc_fault = 8;
  598.     else if (!RbfAllocMatrix(hidden_units,hidden_units,&soll_einheit_sein))
  599.     malloc_fault = 9;
  600. #endif
  601.  
  602.  
  603.     if (malloc_fault != 0){
  604.     if (malloc_fault >= 1)
  605.         RbfFreeMatrix(&hidden_act);
  606.     if (malloc_fault >= 2)
  607.         RbfFreeMatrix(&t_hidden_act);
  608.     if (malloc_fault >= 3)
  609.         RbfFreeMatrix(&hidden_produkt);
  610.     if (malloc_fault >= 4)
  611.         RbfFreeMatrix(&inter_act);
  612.     if (malloc_fault >= 5)
  613.         RbfFreeMatrix(&hidden_sum);
  614.     if (malloc_fault >= 6)
  615.         RbfFreeMatrix(&y_vektor);
  616.     if (malloc_fault >= 7)
  617.         RbfFreeMatrix(&weights_vektor);
  618. #ifdef RBF_MATRIX_TEST
  619.     if (malloc_fault >= 8)
  620.         RbfFreeMatrix(&alt_hidden_sum);
  621.     if (malloc_fault >= 9)
  622.         RbfFreeMatrix(&soll_einheit_sein);
  623. #endif
  624.  
  625.     return KRERR_INSUFFICIENT_MEM;
  626.     }
  627.  
  628.     /* change the following line into '#if 1' to allow deviation only in  */
  629.     /* case that there are more hidden units than learn patterns      */
  630. #if 0
  631.     /* test if more hidden units than learn patterns: */
  632.     if (hidden_units - 1 >= pattern_anz){
  633.  
  634.     /* more hidden units than learn patterns symmetry breaking necessary!*/
  635.     deviation = i_devi;    /* maximum change = i_devi * activation    */
  636.     }else{
  637.     /* less hidden units than learn patterns; no symmetry breaking    */
  638.     deviation = 0.0;       
  639.     }
  640. #else
  641.     /* set deviation to parameter */
  642.     deviation = i_devi;
  643.     
  644. #endif
  645.  
  646.     fprintf(stderr,"... compute activation of hidden layer on centers\n");
  647.  
  648.     /* Now set the centers and fill the inter activation matrix: */
  649.     unit_nr = 0;
  650.     while ((unit_ptr = *(++topo_ptr)) != NULL){
  651.     /* set weights of links leading to <unit_ptr>: */
  652.     if (init_type == RBF_INIT_FULL){
  653.         abs_sub_nr = (((pattern_anz-1)*unit_nr)/(hidden_units-2)) + 
  654.                  start_sp;
  655.         kr_getSubPatternByNo(&pattern_no, &sub_pat_no, abs_sub_nr);
  656.         RbfInitSetCenter(pattern_no, sub_pat_no, unit_ptr, 
  657.                  deviation, i_bias);
  658.     }else{
  659.         RbfInitBPCenter(unit_ptr);
  660.     }
  661.  
  662.     /* calculate activation of previously defined centers on the current */
  663.     /* pattern and store it into the inter activation matrix:         */
  664.     topo_work = topo_hidden_ptr;
  665.     for (h_unit_nr = 0; h_unit_nr <= unit_nr; h_unit_nr++){
  666.         h_unit_ptr = *(topo_work++);
  667.  
  668.         /* calculate activation: */
  669.         h_unit_ptr -> act = h_unit_ptr -> Out.output =
  670.         (*h_unit_ptr -> act_func) (h_unit_ptr);
  671.  
  672.         /* store it into the symmetric matrix: */
  673.         RbfMatrixSetValue(&inter_act, h_unit_nr, unit_nr,
  674.                   h_unit_ptr -> act * i_smooth);
  675.         RbfMatrixSetValue(&inter_act, unit_nr, h_unit_nr,
  676.                   h_unit_ptr -> act * i_smooth);
  677.     }
  678.     unit_nr++;
  679.     }
  680.     
  681.     /* Add entrys for the additional bias: */
  682.     for (h_unit_nr = 0; h_unit_nr < hidden_units; h_unit_nr++){
  683.     RbfMatrixSetValue(&inter_act, h_unit_nr, hidden_units - 1, 
  684.               i_smooth);
  685.     RbfMatrixSetValue(&inter_act, hidden_units - 1, h_unit_nr,
  686.               i_smooth);
  687.     }
  688.  
  689.     fprintf(stderr,"... compute activation of hidden layer on patterns\n");
  690.  
  691.     /* Fill the hidden units activation matrix */
  692.     for (abs_sub_nr = start_sp; abs_sub_nr <= end_sp; abs_sub_nr++){
  693.     kr_getSubPatternByNo(&pattern_no, &sub_pat_no, abs_sub_nr);
  694.     RbfLearnForward(pattern_no, sub_pat_no);
  695.     topo_ptr = topo_hidden_ptr;
  696.     for (unit_nr = 0; unit_nr < hidden_units - 1; unit_nr++){
  697.         RbfMatrixSetValue(&hidden_act, abs_sub_nr - start_sp, unit_nr,
  698.                   (*(topo_ptr++)) -> Out.output);
  699.     }
  700.     }
  701.     
  702.     /* Add entrys for the additional bias: */
  703.     for (h_unit_nr = 0; h_unit_nr < pattern_anz; h_unit_nr++){
  704.     RbfMatrixSetValue(&hidden_act, h_unit_nr, hidden_units - 1, 1.0);
  705.     }
  706.     
  707.     fprintf(stderr,"... calculate the moore-penrose inverse matrix\n");
  708.  
  709.     /* Now calculate the Moore-Penrose Pseudoinverse: */
  710.     fprintf(stderr,"...... transposing\n");
  711.     RbfTranspMatrix(&t_hidden_act, &hidden_act);
  712.     fprintf(stderr,"...... multiplying\n");
  713.     RbfMulTranspMatrix(&hidden_produkt, &t_hidden_act);
  714.     fprintf(stderr,"...... adding\n");
  715.     RbfAddMatrix(&hidden_sum, &hidden_produkt, &inter_act);
  716.  
  717. #ifdef RBF_MATRIX_TEST
  718.     RbfSetMatrix(&alt_hidden_sum, &hidden_sum);
  719. #endif
  720.  
  721.     fprintf(stderr,"...... inverting\n");
  722.     if ((tmp_err = RbfInvMatrix(&hidden_sum)) != 1){
  723.     fprintf(stderr,"... impossible to invert matrix!\n");
  724.     abort = TRUE;
  725.     }
  726.  
  727. #ifdef RBF_MATRIX_TEST
  728.     RbfMulMatrix(&soll_einheit_sein, &alt_hidden_sum, &hidden_sum);
  729.     printf("Einheitsmatrix:\n");
  730.     RbfPrintMatrix(&soll_einheit_sein, stdout);
  731. #endif
  732.  
  733.     if (!abort){
  734.     fprintf(stderr,"...... multiplying\n");
  735.     RbfMulMatrix(&m_p_inverse, &hidden_sum, &t_hidden_act);
  736.  
  737.     fprintf(stderr,
  738.         "... calculate weights between hidden and output layer\n");
  739.     
  740.     /* set topo_ptr to the NULL between hidden and output layer: */
  741.     topo_ptr = topo_hidden_ptr;
  742.     while(*(++topo_ptr) != NULL);
  743.  
  744.     /* direct calc. of all weights of links leading to the output layer: */
  745.     unit_nr = 0;  /* counts the output units */
  746.     while((unit_ptr = *(++topo_ptr)) != NULL){
  747.  
  748.         /* fill the y_vektor with the desired outputs for all patterns: */
  749.         for (abs_sub_nr = start_sp; abs_sub_nr <= end_sp; abs_sub_nr++){
  750.         kr_getSubPatternByNo(&pattern_no, &sub_pat_no, abs_sub_nr);
  751.         current_out_pattern = kr_getSubPatData(pattern_no,
  752.                                sub_pat_no,
  753.                                OUTPUT, NULL);
  754.         RbfMatrixSetValue(&y_vektor, abs_sub_nr - start_sp, 0,
  755.                   i_f_0 + (i_f_1 - i_f_0)*
  756.                   *(current_out_pattern + unit_nr));
  757.         }
  758.  
  759.         /* calculate the weights, leading to the current output unit*/
  760.         RbfMulMatrix(&weights_vektor, &m_p_inverse, &y_vektor);
  761.  
  762.         /* temporarely store the weights in the value_c field of    */
  763.         /* the corresponding hidden units:                */
  764.         topo_work = topo_hidden_ptr;
  765.         h_unit_nr = 0;
  766.         do {
  767.         (*(topo_work++)) -> value_c = 
  768.             RbfMatrixGetValue(&weights_vektor, h_unit_nr++, 0); 
  769.         } while (*topo_work != NULL);
  770.  
  771.         /* set the bias of the output unit:    */
  772.         unit_ptr->bias = 
  773.         RbfMatrixGetValue(&weights_vektor, hidden_units - 1, 0);
  774.  
  775.         /* set the weights of the links: */
  776.         FOR_ALL_LINKS(unit_ptr, link_ptr) {
  777.         link_ptr -> weight = link_ptr -> to -> value_c;
  778.         }
  779.         unit_nr++;
  780.     }
  781.  
  782.     fprintf(stderr,"Initialization done !\n");
  783.     }else{
  784.     if (tmp_err == 0)
  785.         fprintf(stderr,"singular matrix !\n");
  786.     fprintf(stderr,"Initialization aborted !\n");
  787.     }
  788.     RbfFreeMatrix(&hidden_act);
  789.     RbfFreeMatrix(&t_hidden_act);
  790.     RbfFreeMatrix(&hidden_produkt);
  791.     RbfFreeMatrix(&inter_act);
  792.     RbfFreeMatrix(&hidden_sum);
  793.     RbfFreeMatrix(&y_vektor);
  794.     RbfFreeMatrix(&weights_vektor);
  795.     RbfFreeMatrix(&m_p_inverse);
  796.  
  797.     if (abort){
  798.     return tmp_err == 0 ? KRERR_NO_ERROR : tmp_err;
  799.     }else{
  800.     return KRERR_NO_ERROR;
  801.     }
  802. }
  803.  
  804.  
  805.  
  806. #ifdef RBF_INCLUDE_KOHONEN_CONVEX
  807. /*****************************************************************************
  808.   FUNCTION : RbfKohonenConvexInit
  809.  
  810.   PURPOSE  :
  811.   RETURNS  : 
  812.   NOTES    :
  813.  
  814.   UPDATE   : 
  815. ******************************************************************************/
  816. void RbfKohonenConvexInit(int start_pattern,int end_pattern,float alpha_start,
  817.               float alpha_increment,float learn_rate,int count)
  818. {
  819.     register float        scalar_prod;    /* act. scalar product    */
  820.     register float        maximum;    /* max scalar product    */
  821.     register struct Link    *link_ptr;    /* current Link        */
  822.     register struct Unit    *unit_ptr;    /* current Unit        */
  823.     register TopoPtrArray    topo_ptr;
  824.     register Patterns    current_in_pattern;    /* in pattern    */
  825.     register int        pattern_no;
  826.     register int            sub_pat_no;
  827.     register TopoPtrArray    topo_hidden_ptr;/* first hidden Unit    */
  828.     register float        alpha;        /* convex combination    */
  829.     register struct Unit    *winner;    /* Unit who's links    */
  830.                         /* change        */
  831.     register float        norm_alpha;    /* convex combination    */
  832.     float            norm_init;    /* initialization value    */
  833.     
  834.     /* search for the first hidden unit                */
  835.     topo_ptr = topo_ptr_array;
  836.     while (*(++topo_ptr) != NULL);        /* empty loop!        */
  837.  
  838.     /* reference to first hidden unit                */
  839.     topo_hidden_ptr = topo_ptr;
  840.     topo_hidden_ptr++;
  841.  
  842.     /* initialize all weights leading to hidden units        */
  843.     norm_init = 1.0 / (float) sqrt((float) NoOfInputUnits);
  844.     while ((unit_ptr = *(++topo_ptr)) != NULL)
  845.     {
  846.         FOR_ALL_LINKS(unit_ptr, link_ptr)
  847.         {
  848.         link_ptr -> weight = norm_init;
  849.         }
  850.     }
  851.  
  852.     /* do the kohonen training <count> times with increasing alpha    */
  853.     for (alpha = alpha_start; count > 0; alpha += alpha_increment, count--)
  854.     {
  855.         /* precalculate the constant value for the convex        */
  856.         /* combination method for the current alpha            */
  857.         norm_alpha = (1.0 - alpha) * norm_init;
  858.  
  859.         /* compute the necessary sub patterns */
  860.         KernelErrorCode = kr_initSubPatternOrder(start_pattern,
  861.                              end_pattern);
  862.         if(KernelErrorCode != KRERR_NO_ERROR)
  863.         return (KernelErrorCode);
  864.  
  865.         /* present all input patterns and train the hidden layer */
  866.         while(kr_getSubPatternByOrder(&pattern_no,&sub_pat_no))
  867.         {
  868.         /* calculate index of first component of input pattern */
  869.         current_in_pattern = kr_getSubPatData(pattern_no,
  870.                               sub_pat_no,
  871.                               INPUT, NULL);
  872.  
  873.         /* activate input units with the pattern and calculate    */
  874.         /* their output value:                    */
  875.         topo_ptr = topo_ptr_array;
  876.         while ((unit_ptr = *(++topo_ptr)) != NULL)
  877.         {
  878.             /* go through all input units, set activation and    */
  879.             /* calculate output using the convex combination    */
  880.             /* method                        */
  881.             unit_ptr -> act = *current_in_pattern++;
  882.             unit_ptr -> Out.output = unit_ptr->out_func==OUT_IDENTITY 
  883.             ? alpha * (unit_ptr -> act) + norm_alpha
  884.             : alpha * ((*unit_ptr -> out_func) (unit_ptr -> act))
  885.                 + norm_alpha;
  886.         }
  887.  
  888.         /* determine the hidden unit with maximum scalar product*/
  889.         /* between its weights and the output of the input layer*/
  890.         winner = (struct Unit *) NULL;
  891.         maximum = (float) -MY_HUGE_VAL;    /* -oo, see init_f.ph    */
  892.         topo_ptr = topo_hidden_ptr;
  893.         while ((unit_ptr = *(topo_ptr++)) != NULL)
  894.         {
  895.             /* calculate scalar product of current hidden unit    */
  896.             scalar_prod = (float) 0.0;
  897.             FOR_ALL_LINKS(unit_ptr, link_ptr)
  898.             {
  899.             scalar_prod += link_ptr -> weight * 
  900.                 link_ptr -> to -> Out.output;
  901.             }
  902.  
  903.             /* change winner if s.p. is > than the current best    */
  904.             if (scalar_prod > maximum)
  905.             {
  906.             maximum = scalar_prod;
  907.             winner = unit_ptr;
  908.             }
  909.         }
  910.  
  911.         /* adjust weights of the hidden winner Unit        */
  912.         if (winner != NULL)
  913.         {
  914.             FOR_ALL_LINKS(winner, link_ptr)
  915.             {
  916.             link_ptr -> weight += learn_rate * 
  917.                 (link_ptr->to->Out.output - link_ptr->weight);
  918.             }
  919.             printf("(%d,%d) ", winner -> unit_pos.x, 
  920.             winner -> unit_pos.y); 
  921.         }
  922.         else
  923.         {
  924.             fprintf(stderr,"Internal error in RbfKohonenConvexInit\n");
  925.         }
  926.         }
  927.     }
  928. }
  929.  
  930. #endif
  931.  
  932. krui_err RbfKohonenInit(int start_pattern, int end_pattern, float learn_rate, int count, int shuffle)
  933. {
  934.     register float        scalar_prod;    /* act. scalar product    */
  935.     register float        maximum;    /* max scalar product    */
  936.     register struct Link    *link_ptr;    /* current Link        */
  937.     register struct Unit    *unit_ptr;    /* current Unit        */
  938.     register TopoPtrArray    topo_ptr;
  939.     register Patterns    current_in_pattern;    /* in pattern    */
  940.     int                 pattern_no;
  941.     int                     sub_pat_no;
  942.     register int            start_sp;
  943.     register int            end_sp;
  944.     register int            act_sub_nr;
  945.     register TopoPtrArray    topo_hidden_ptr;/* first hidden Unit    */
  946.     register TopoPtrArray    help_topo_ptr;
  947.     register struct Unit    *winner;    /* Unit who's links    */
  948.                         /* change        */
  949.     float            norm_init;    /* initialization value    */
  950.     register struct Unit    *hidden_unit;    /* current hidden unit    */
  951.     register int        hidden_units;    /* number of hidden u.    */
  952.     register int        act_hidden_num;    /* number of current hu.*/
  953.     int            reshuffle;    /* restore shuffled p.    */
  954.  
  955.     fprintf(stderr, "RBF_Weights_Kohonen called, start initialization:\n");
  956.  
  957.     /* search for the first hidden unit                */
  958.     topo_ptr = topo_ptr_array;
  959.     while (*(++topo_ptr) != NULL);        /* empty loop!        */
  960.  
  961.     /* count hidden units and reference to first hidden unit    */
  962.     topo_hidden_ptr = topo_ptr;
  963.     hidden_units = 0;
  964.     while (*(++topo_hidden_ptr) != NULL)
  965.         hidden_units++;
  966.     topo_hidden_ptr = topo_ptr;
  967.     topo_hidden_ptr++;
  968.  
  969.     if (shuffle)
  970.     {
  971.         reshuffle = FALSE;
  972.         if (!kr_np_pattern(GET_SHUFFLE_FLAG, 0, 0))
  973.         {
  974.         kr_np_pattern(PATTERN_SHUFFLE_ON, 0, 0);
  975.         reshuffle = TRUE;
  976.         }
  977.     }
  978.  
  979.     /* compute the necessary sub patterns */
  980.     KernelErrorCode = kr_initSubPatternOrder(start_pattern, end_pattern);
  981.     if(KernelErrorCode != KRERR_NO_ERROR)
  982.         return (KernelErrorCode);
  983.  
  984.     start_sp = kr_AbsPosOfFirstSubPat(start_pattern);
  985.     end_sp = kr_AbsPosOfFirstSubPat(end_pattern) + 
  986.         kr_NoOfSubPatPairs(end_pattern) - 1;
  987.     
  988.     fprintf(stderr, "... init weights between input and hidden layer\n");
  989.  
  990.     /* initialize all weights leading to hidden units        */
  991.     norm_init = 1.0 / (float) sqrt((float) NoOfInputUnits);
  992.     act_hidden_num = 0;
  993.     while ((hidden_unit = *(++topo_ptr)) != NULL)
  994.     {
  995.         if (shuffle)
  996.         {
  997.         /* shuffle                        */
  998.         if (!kr_getSubPatternByOrder(&pattern_no, &sub_pat_no))
  999.             return KRERR_PATTERN_NO;
  1000.         }
  1001.         else
  1002.         {
  1003.         /* do not shuffle                    */
  1004.         act_sub_nr = start_sp + 
  1005.             ((end_sp-start_sp) * act_hidden_num) / (hidden_units - 1);
  1006.         if (!kr_getSubPatternByNo(&pattern_no, &sub_pat_no, 
  1007.                       act_sub_nr))
  1008.             return KRERR_PATTERN_NO;
  1009.         }
  1010.  
  1011.         /* calculate index of input pattern */
  1012.         current_in_pattern = kr_getSubPatData(pattern_no,
  1013.                           sub_pat_no, INPUT,
  1014.                           NULL);
  1015.  
  1016.         /* activate input units with the pattern and calculate    */
  1017.         /* their output value:                    */
  1018.         help_topo_ptr = topo_ptr_array;
  1019.         while ((unit_ptr = *(++help_topo_ptr)) != NULL)
  1020.         {
  1021.         /* go through all input units, set activation and    */
  1022.         /* calculate output using the convex combination    */
  1023.         /* method                        */
  1024.         unit_ptr -> act = *current_in_pattern++;
  1025.         unit_ptr -> Out.output = unit_ptr->out_func==OUT_IDENTITY 
  1026.             ? (unit_ptr -> act)
  1027.             : ((*unit_ptr -> out_func) (unit_ptr -> act));
  1028.         }
  1029.  
  1030.         FOR_ALL_LINKS(hidden_unit, link_ptr)
  1031.         {
  1032.         link_ptr -> weight = link_ptr -> to -> Out.output;
  1033.         }
  1034.  
  1035.         act_hidden_num++;
  1036.     }
  1037.  
  1038.     if (shuffle && reshuffle)
  1039.     {
  1040.         kr_np_pattern(PATTERN_SHUFFLE_OFF, 0, 0);
  1041.     }
  1042.  
  1043.     /* do the kohonen training <count> times            */
  1044.     if (count > 0)
  1045.     {
  1046.        fprintf(stderr, "... begin kohonen training\n");
  1047.     }
  1048.     for (; count > 0; count--)
  1049.     {
  1050.         /* compute the necessary sub patterns */
  1051.         KernelErrorCode = kr_initSubPatternOrder(start_pattern, 
  1052.                              end_pattern);
  1053.         if(KernelErrorCode != KRERR_NO_ERROR)
  1054.         return (KernelErrorCode);
  1055.  
  1056.         /* present all input patterns and train the hidden layer    */
  1057.         while(kr_getSubPatternByOrder(&pattern_no, &sub_pat_no))
  1058.         {
  1059.         /* calculate index of input pattern */
  1060.         current_in_pattern = kr_getSubPatData(pattern_no,
  1061.                               sub_pat_no,
  1062.                               INPUT, NULL);
  1063.  
  1064.         /* activate input units with the pattern and calculate    */
  1065.         /* their output value:                    */
  1066.         topo_ptr = topo_ptr_array;
  1067.         while ((unit_ptr = *(++topo_ptr)) != NULL)
  1068.         {
  1069.             /* go through all input units, set activation and    */
  1070.             /* calculate output using the convex combination    */
  1071.             /* method                        */
  1072.             unit_ptr -> act = *current_in_pattern++;
  1073.             unit_ptr -> Out.output = unit_ptr->out_func==OUT_IDENTITY 
  1074.             ? (unit_ptr -> act)
  1075.             : ((*unit_ptr -> out_func) (unit_ptr -> act));
  1076.         }
  1077.  
  1078.         /* determine the hidden unit with maximum scalar product*/
  1079.         /* between its weights and the output of the input layer*/
  1080.         winner = (struct Unit *) NULL;
  1081.         maximum = (float) -MY_HUGE_VAL;    /* -oo, see init_f.ph    */
  1082.         topo_ptr = topo_hidden_ptr;
  1083.         while ((unit_ptr = *(topo_ptr++)) != NULL)
  1084.         {
  1085.             /* calculate scalar product of current hidden unit    */
  1086.             scalar_prod = (float) 0.0;
  1087.             FOR_ALL_LINKS(unit_ptr, link_ptr)
  1088.             {
  1089.             scalar_prod += link_ptr -> weight * 
  1090.                 link_ptr -> to -> Out.output;
  1091.             }
  1092.  
  1093.             /* change winner if s.p. is > than the current best    */
  1094.             if (scalar_prod > maximum)
  1095.             {
  1096.             maximum = scalar_prod;
  1097.             winner = unit_ptr;
  1098.             }
  1099.         }
  1100.  
  1101.         /* adjust weights of the hidden winner Unit        */
  1102.         if (winner != NULL)
  1103.         {
  1104.             FOR_ALL_LINKS(winner, link_ptr)
  1105.             {
  1106.             link_ptr -> weight += learn_rate * 
  1107.                 (link_ptr->to->Out.output - link_ptr->weight);
  1108.             }
  1109.         }
  1110.         else
  1111.         {
  1112.             fprintf(stderr,"Internal error in RbfKohonenConvexInit\n");
  1113.         }
  1114.         }
  1115.     }
  1116.     fprintf(stderr, "Initialization done\n");
  1117.     return KRERR_NO_ERROR;
  1118. }
  1119.  
  1120. krui_err RbfStartInit(float *parameterArray, int NoOfParams, int init_type)
  1121. {
  1122.     krui_err    ret_code;    /* error return code        */
  1123.     float        bias;        /* bias of hidden units        */
  1124.     float        deviation;    /* deviation of centers        */
  1125.     float        f_0_lin;    /* learning value for pattern==0*/
  1126.     float        f_1_lin;    /* learning value for pattern==1*/
  1127.     float        smoothness;    /* see documentation         */
  1128.  
  1129.     float        learn_rate;    /* kohonen training rate    */
  1130.     int        count;        /* cycles for kohonen training  */
  1131.  
  1132.     /* for future use, now uncommented:                 */
  1133.     /* check the number of input parameters                */
  1134.  
  1135.     /* test if patterns available and valid:            */
  1136.     if (kr_TotalNoOfSubPatPairs() == 0)  
  1137.         return( KRERR_NO_PATTERNS );    /* no patterns defined  */
  1138.  
  1139.     /* test net topology:                        */
  1140.     if (NetModified || (TopoSortID != TOPOLOGICAL_FF))
  1141.     {
  1142.         ret_code = RbfTopoCheck();    /* in learn_f.c            */
  1143.  
  1144.         if ((ret_code != KRERR_NO_ERROR) && (ret_code != KRERR_DEAD_UNITS))
  1145.         return( ret_code );
  1146.  
  1147.         NetModified = FALSE;
  1148.     }
  1149.  
  1150.     switch(init_type)
  1151.     {
  1152.         case RBF_INIT_FULL:
  1153.         case RBF_INIT_REINIT:
  1154.         /* read input parameters:                */
  1155.         bias = INIT_PARAM4(parameterArray);
  1156.         deviation = INIT_PARAM5(parameterArray);
  1157.         f_0_lin = INIT_PARAM1(parameterArray);
  1158.         f_1_lin = INIT_PARAM2(parameterArray);
  1159.         smoothness = INIT_PARAM3(parameterArray);
  1160.  
  1161.         /* call real initialization function:            */
  1162.         ret_code = RbfInitNetwork(0, kr_TotalNoOfPattern() - 1, bias, 
  1163.             deviation, f_0_lin, f_1_lin, smoothness, init_type);
  1164.         break;
  1165.  
  1166.         case RBF_INIT_KOHONEN:
  1167.         /* read input parameters:                */
  1168.         count = (int) (INIT_PARAM1(parameterArray));
  1169.         learn_rate = INIT_PARAM2(parameterArray);
  1170.         ret_code = RbfKohonenInit(0, kr_TotalNoOfPattern() - 1,
  1171.                       learn_rate, count, 
  1172.                       INIT_PARAM3(parameterArray) != 0.0);
  1173.         break;
  1174.     }
  1175.  
  1176.     return ret_code;
  1177. }
  1178.  
  1179. /*
  1180.  * Use of initialization parameters:
  1181.  * RBF_Weights: (5)
  1182.  *   INIT_PARAM1: interpolation value for teaching pattern == 0.0
  1183.  *                (see documentation)
  1184.  *   INIT_PARAM2: interpolation value for teaching pattern == 1.0
  1185.  *                (see documentation)
  1186.  *   INIT_PARAM3: smoothness parameter
  1187.  *   INIT_PARAM4: initialization bias of hidden units
  1188.  *   INIT_PARAM5: deviation parameter for symmetry breaking
  1189.  * RBF_Weights_redo: (3)
  1190.  *   INIT_PARAM1: interpolation value for teaching pattern == 0.0
  1191.  *                (see documentation)
  1192.  *   INIT_PARAM2: interpolation value for teaching pattern == 1.0
  1193.  *                (see documentation)
  1194.  *   INIT_PARAM3: smoothness parameter
  1195.  * RBF_Weights_Kohonen: (3)
  1196.  *   INIT_PARAM1: number of cycles for the kohonen training
  1197.  *   INIT_PARAM2: learn_rate for kohonen training
  1198.  *   INIT_PARAM3: shuffle flag:
  1199.  *                0.0 = the patterns are normally distributed over the links
  1200.  *                      to the hidden units.
  1201.  *             != 0.0 = the patterns to use are randomly taken from all
  1202.  *                      available patterns.
  1203.  */
  1204.  
  1205. krui_err INIT_RBF_Weights(float *parameterArray, int NoOfParams)
  1206. {
  1207.     return RbfStartInit(parameterArray, NoOfParams, RBF_INIT_FULL);
  1208. }
  1209.  
  1210. krui_err INIT_RBF_Weights_redo(float *parameterArray, int NoOfParams)
  1211. {
  1212.     return RbfStartInit(parameterArray, NoOfParams, RBF_INIT_REINIT);
  1213. }
  1214.  
  1215. krui_err INIT_RBF_Weights_kohonen(float *parameterArray, int NoOfParams)
  1216. {
  1217.     return RbfStartInit(parameterArray, NoOfParams, RBF_INIT_KOHONEN);
  1218. }
  1219.  
  1220.  
  1221.  
  1222.  
  1223. /* Initializes an ART1 network
  1224. */
  1225. krui_err INIT_Weights_ART1(float *parameterArray, int NoOfParams)
  1226. {
  1227.   register struct Unit    *unit_ptr;
  1228.   register struct Link    *link_ptr;
  1229.  
  1230.   TopoPtrArray            topo_cmp_ptr,
  1231.                           topo_rec_ptr,
  1232.                           topo_ptr;
  1233.  
  1234.   int                     ret_code       = KRERR_NO_ERROR;
  1235.  
  1236.   FlintType               beta;
  1237.   FlintType               gamma;
  1238.   double                  eta;
  1239.  
  1240.   int                     j;
  1241.  
  1242.  
  1243.   if ( (unit_array == NULL) || (NoOfUnits == 0) ) {
  1244.      ret_code = KRERR_NO_UNITS;
  1245.      return( ret_code );         /*  there is nothing to do  */
  1246.   } /*if*/
  1247.  
  1248.   if (NoOfParams < 2) {
  1249.      ret_code = KRERR_PARAMETERS;
  1250.      return( ret_code );  /*  Not the same no. of input parameters */
  1251.   } /*if*/
  1252.  
  1253.   beta = parameterArray [0];
  1254.   gamma = parameterArray [1];
  1255.  
  1256.  
  1257.   if ((beta <= 0.0) || (gamma <= 0.0)) {
  1258.      /* the parameters beta and gamma have to be greater than 0.0
  1259.      */
  1260.      ret_code = KRERR_PARAMETERS;
  1261.      return (ret_code);
  1262.   } /*if*/
  1263.  
  1264.   ret_code = kr_topoSort (ART1_TOPO_TYPE);
  1265.   if (ret_code != KRERR_NO_ERROR) {
  1266.      NetModified = TRUE;
  1267.      return (ret_code);
  1268.   } /*if*/
  1269.   NetModified = FALSE;
  1270.  
  1271.  
  1272.   /* Now we will write the value of beta in each of the units of the
  1273.      network for to be able to recall in the learning algorithm.
  1274.      The value will be written to the bias field of the unit structure
  1275.      which is not needed for ART 1 learning in any other way and which
  1276.      has the property that it is written to the netfile when the network
  1277.      is saved.
  1278.   */
  1279.   FOR_ALL_UNITS (unit_ptr) {
  1280.      unit_ptr->bias = beta;
  1281.   } /*FOR_ALL_UNITS*/
  1282.  
  1283.   topo_cmp_ptr = topo_ptr_array + NoOfInputUnits + 2;
  1284.   topo_rec_ptr = topo_cmp_ptr   + NoOfInputUnits + 1;
  1285.  
  1286.  
  1287.   /* To initialize the bottom up weight values we have to choose one
  1288.      value for each recognition unit. That is, each weight value for
  1289.      a link to a recognition unit j is set to
  1290.  
  1291.                      b(i,j) = alpha(j),
  1292.  
  1293.      where the alpha(j) are to be choosen as follows
  1294.  
  1295.           alpha(1) > alpha(2) > .... > alpha (M) where M is the no. of
  1296.                                                  rec. unit.
  1297.  
  1298.      and    0 < alpha(j) < 1/(beta + |I|)  for all 1 <= j <= M.
  1299.  
  1300.      For this reason we partition gamma
  1301.      into M parts (eta=(gamma/M) and init as follows
  1302.  
  1303.       b(i,j) = alpha(1) = 1/(beta + (1.0 + j*eta) * |I|)
  1304.       for all 1 <= j <= M
  1305.   */
  1306.  
  1307.   eta = gamma / Art1_NoOfRecUnits;
  1308.  
  1309.   /* init weights from comparison units to recognition units */
  1310.   topo_ptr = topo_rec_ptr;
  1311.  
  1312.   j = 1;
  1313.   while ((unit_ptr = *topo_ptr++) != NULL) {
  1314.  
  1315.      if (UNIT_HAS_SITES (unit_ptr)) {
  1316.         ret_code = KRERR_TOPOLOGY;
  1317.         return (ret_code);
  1318.      } /*if*/
  1319.  
  1320.      FOR_ALL_LINKS (unit_ptr, link_ptr) {
  1321.  
  1322.         if (link_ptr->to->lln == ART1_CMP_LAY) {
  1323.            link_ptr->weight = ART1_LINK_CMP_REC(beta, (1.0+j*eta));
  1324.         } /*if*/
  1325.  
  1326.       } /*FOR_ALL_LINKS*/
  1327.  
  1328.       j++;
  1329.  
  1330.   } /*while*/
  1331.  
  1332.  
  1333.   /* init weights from delay units to comparison units */
  1334.   topo_ptr = topo_cmp_ptr;
  1335.  
  1336.   while ((unit_ptr = *topo_ptr++) != NULL) {
  1337.  
  1338.      if (UNIT_HAS_SITES (unit_ptr)) {
  1339.         ret_code = KRERR_TOPOLOGY;
  1340.         return (ret_code);
  1341.      } /*if*/
  1342.  
  1343.      FOR_ALL_LINKS (unit_ptr, link_ptr) {
  1344.  
  1345.         if (link_ptr->to->lln == ART1_DEL_LAY) {
  1346.            link_ptr->weight = ART1_LINK_DEL_CMP;
  1347.         } /*if*/
  1348.  
  1349.       } /*FOR_ALL_LINKS*/
  1350.  
  1351.   } /*while*/
  1352.  
  1353.  
  1354.  
  1355.   return (ret_code);
  1356.  
  1357. } /* INIT_Weights_ART1 */
  1358.  
  1359.  
  1360.  
  1361.  
  1362.  
  1363. /* Initializes an ART2 network
  1364. */
  1365. krui_err INIT_Weights_ART2(float *parameterArray, int NoOfParams)
  1366. {
  1367.   register struct Unit    *unit_ptr;
  1368.   register struct Link    *link_ptr;
  1369.  
  1370.   TopoPtrArray            topo_p_ptr,
  1371.                           topo_rec_ptr,
  1372.                           topo_ptr;
  1373.  
  1374.   int                     ret_code       = KRERR_NO_ERROR;
  1375.  
  1376.   FlintType               param_d;
  1377.   FlintType               gamma;
  1378.  
  1379.  
  1380.   if ( (unit_array == NULL) || (NoOfUnits == 0) ) {
  1381.      ret_code = KRERR_NO_UNITS;
  1382.      return( ret_code );         /*  there is nothing to do  */
  1383.   } /*if*/
  1384.  
  1385.   if (NoOfParams < 1) {
  1386.      ret_code = KRERR_PARAMETERS;
  1387.      return( ret_code );  /*  Not the same no. of input parameters */
  1388.   } /*if*/
  1389.  
  1390.   param_d = parameterArray [0];
  1391.   gamma   = parameterArray [1];
  1392.  
  1393.  
  1394.   if ((param_d <= 0.0) || (param_d >= 1.0) ||
  1395.       (gamma < 1.0))
  1396.   {
  1397.      /* the parameters d has to fit the constraint 0 < d < 1,
  1398.         gamma >= 1.0
  1399.      */
  1400.      ret_code = KRERR_PARAMETERS;
  1401.      return (ret_code);
  1402.   } /*if*/
  1403.  
  1404.   ret_code = kr_topoSort (ART2_TOPO_TYPE);
  1405.   if (ret_code != KRERR_NO_ERROR) {
  1406.      NetModified = TRUE;
  1407.      return (ret_code);
  1408.   } /*if*/
  1409.   NetModified = FALSE;
  1410.  
  1411.  
  1412.   /* Now we will write the value of param_d in each of the units of the
  1413.      network for to be able to recall in the learning algorithm.
  1414.      The value will be written to the bias field of the unit structure
  1415.      which is not needed for ART 2 learning in any other way and which
  1416.      has the property that it is written to the netfile when the network
  1417.      is saved.
  1418.   */
  1419.   FOR_ALL_UNITS (unit_ptr) {
  1420.      unit_ptr->bias = param_d;
  1421.   } /*FOR_ALL_UNITS*/
  1422.  
  1423.   topo_p_ptr   = topo_ptr_array + 5*NoOfInputUnits + 6;
  1424.   topo_rec_ptr = topo_ptr_array + 8*NoOfInputUnits + 9;
  1425.  
  1426.   /*
  1427.      The ART 2 bottom up links are initialized with the following values:
  1428.  
  1429.          zij(0) = 1 / (gamma * (1-d) * SQRT(N))
  1430.  
  1431.      where gamma is parameter gamma, d is parameter param_d, N
  1432.      is the number of F1-nodes.
  1433.  
  1434.      Choosing gamma as small as possible (gamma=1.0) biases the
  1435.      ART2 system as much as possible toward choosing uncommited
  1436.      nodes.
  1437.   */
  1438.  
  1439.  
  1440.  
  1441.   /* init weights from p units to recognition units (Bottom-Up-Weights) */
  1442.   topo_ptr = topo_rec_ptr;
  1443.  
  1444.   while ((unit_ptr = *topo_ptr++) != NULL) {
  1445.  
  1446.      if (UNIT_HAS_SITES (unit_ptr)) {
  1447.         ret_code = KRERR_TOPOLOGY;
  1448.         return (ret_code);
  1449.      } /*if*/
  1450.  
  1451.      FOR_ALL_LINKS (unit_ptr, link_ptr) {
  1452.  
  1453.         if (link_ptr->to->lln == ART2_P_LAY) {
  1454.            link_ptr->weight = ART2_LINK_P_REC(param_d, gamma);
  1455.         } /*if*/
  1456.  
  1457.       } /*FOR_ALL_LINKS*/
  1458.  
  1459.   } /*while*/
  1460.  
  1461.  
  1462.   /* init weights from delay units to p units (Top-Down-Weights) */
  1463.   topo_ptr = topo_p_ptr;
  1464.  
  1465.   while ((unit_ptr = *topo_ptr++) != NULL) {
  1466.  
  1467.      if (UNIT_HAS_SITES (unit_ptr)) {
  1468.         ret_code = KRERR_TOPOLOGY;
  1469.         return (ret_code);
  1470.      } /*if*/
  1471.  
  1472.      FOR_ALL_LINKS (unit_ptr, link_ptr) {
  1473.  
  1474.         if (link_ptr->to->lln == ART2_REC_LAY) {
  1475.            link_ptr->weight = ART2_LINK_REC_P;
  1476.         } /*if*/
  1477.  
  1478.       } /*FOR_ALL_LINKS*/
  1479.  
  1480.   } /*while*/
  1481.  
  1482.  
  1483.  
  1484.   return (ret_code);
  1485.  
  1486. } /* INIT_Weights_ART2 */
  1487.  
  1488.  
  1489.  
  1490.  
  1491.  
  1492. /* Initializes an ARTMAP network
  1493. */
  1494. krui_err INIT_Weights_ARTMAP(float *parameterArray, int NoOfParams)
  1495. {
  1496.   register struct Unit    *unit_ptr;
  1497.   register struct Link    *link_ptr;
  1498.  
  1499.   TopoPtrArray            topo_cmpa_ptr,
  1500.                           topo_reca_ptr,
  1501.                           topo_cmpb_ptr,
  1502.                           topo_recb_ptr,
  1503.                           topo_map_ptr,
  1504.                           topo_ptr;
  1505.  
  1506.   int                     ret_code       = KRERR_NO_ERROR;
  1507.  
  1508.   FlintType               beta_a, beta_b;
  1509.   FlintType               gamma_a, gamma_b;
  1510.   double                  eta_a, eta_b;
  1511.  
  1512.   int                     j;
  1513.  
  1514.  
  1515.   if ( (unit_array == NULL) || (NoOfUnits == 0) ) {
  1516.      ret_code = KRERR_NO_UNITS;
  1517.      return( ret_code );         /*  there is nothing to do  */
  1518.   } /*if*/
  1519.  
  1520.   if (NoOfParams < 4) {
  1521.      ret_code = KRERR_PARAMETERS;
  1522.      return( ret_code );  /*  Not the same no. of input parameters */
  1523.   } /*if*/
  1524.  
  1525.   beta_a  = parameterArray [0];
  1526.   gamma_a = parameterArray [1];
  1527.   beta_b  = parameterArray [2];
  1528.   gamma_b = parameterArray [3];
  1529.  
  1530.  
  1531.   if ((beta_a <= 0.0) || (gamma_a <= 0.0) || 
  1532.       (beta_b <= 0.0) || (gamma_b <= 0.0)) {
  1533.      /* the parameters beta and gamma have to be greater than 0.0
  1534.      */
  1535.      ret_code = KRERR_PARAMETERS;
  1536.      return (ret_code);
  1537.   } /*if*/
  1538.  
  1539.   ret_code = kr_topoSort (ARTMAP_TOPO_TYPE);
  1540.   if (ret_code != KRERR_NO_ERROR) {
  1541.      NetModified = TRUE;
  1542.      return (ret_code);
  1543.   } /*if*/
  1544.   NetModified = FALSE;
  1545.  
  1546.  
  1547.   /* Now we will write the value of beta in each of the units of the
  1548.      network for to be able to recall in the learning algorithm.
  1549.      The value will be written to the bias field of the unit structure
  1550.      which is not needed for ART 1 learning in any other way and which
  1551.      has the property that it is written to the netfile when the network
  1552.      is saved.
  1553.   */
  1554.   FOR_ALL_UNITS (unit_ptr) {
  1555.      switch (unit_ptr->lln) {
  1556.      case ARTMAP_INPa_LAY:
  1557.      case ARTMAP_CMPa_LAY:
  1558.      case ARTMAP_RECa_LAY:
  1559.      case ARTMAP_DELa_LAY:
  1560.      case ARTMAP_RSTa_LAY:
  1561.      case ARTMAP_SPECa_LAY:
  1562.         unit_ptr->bias = beta_a;
  1563.         break;
  1564.      case ARTMAP_INPb_LAY:
  1565.      case ARTMAP_CMPb_LAY:
  1566.      case ARTMAP_RECb_LAY:
  1567.      case ARTMAP_DELb_LAY:
  1568.      case ARTMAP_RSTb_LAY:
  1569.      case ARTMAP_SPECb_LAY:
  1570.         unit_ptr->bias = beta_b;
  1571.         break;
  1572.      default:
  1573.         break;
  1574.      } /*switch*/
  1575.   } /*FOR_ALL_UNITS*/
  1576.  
  1577.   topo_cmpa_ptr = topo_ptr_array + ArtMap_NoOfInpUnits_a + 2;
  1578.  
  1579.   topo_reca_ptr = topo_cmpa_ptr  + ArtMap_NoOfInpUnits_a + 1;
  1580.  
  1581.   topo_cmpb_ptr = topo_reca_ptr  + 3*ArtMap_NoOfRecUnits_a
  1582.                                  + ARTMAP_NO_OF_SPECa_UNITS
  1583.                                  + ArtMap_NoOfInpUnits_b
  1584.                                  + 8;
  1585.  
  1586.   topo_recb_ptr = topo_cmpb_ptr  + ArtMap_NoOfInpUnits_b + 1;
  1587.  
  1588.   topo_map_ptr  = topo_recb_ptr  + 3*ArtMap_NoOfRecUnits_b
  1589.                                  + ARTMAP_NO_OF_SPECb_UNITS
  1590.                                  + 7;
  1591.  
  1592.  
  1593.   /* To initialize the bottom up weight values we have to choose one
  1594.      value for each recognition unit. That is, each weight value for
  1595.      a link to a recognition unit j is set to
  1596.  
  1597.                      b(i,j) = alpha(j),
  1598.  
  1599.      where the alpha(j) are to be choosen as follows
  1600.  
  1601.           alpha(1) > alpha(2) > .... > alpha (M) where M is the no. of
  1602.                                                  rec. unit.
  1603.  
  1604.      and    0 < alpha(j) < 1/(beta + |I|)  for all 1 <= j <= M.
  1605.  
  1606.      For this reason we partition gamma
  1607.      into M parts (eta=(gamma/M) and init as follows
  1608.  
  1609.       b(i,j) = alpha(1) = 1/(beta + (1.0 + j*eta) * |I|)
  1610.       for all 1 <= j <= M
  1611.   */
  1612.  
  1613.   eta_a = gamma_a / ArtMap_NoOfRecUnits_a;
  1614.   eta_b = gamma_b / ArtMap_NoOfRecUnits_b;
  1615.  
  1616.   /* init weights from comparison units to recognition units for ARTa
  1617.   */
  1618.   topo_ptr = topo_reca_ptr;
  1619.  
  1620.   j = 1;
  1621.   while ((unit_ptr = *topo_ptr++) != NULL) {
  1622.  
  1623.      if (UNIT_HAS_SITES (unit_ptr)) {
  1624.         ret_code = KRERR_TOPOLOGY;
  1625.         return (ret_code);
  1626.      } /*if*/
  1627.  
  1628.      FOR_ALL_LINKS (unit_ptr, link_ptr) {
  1629.  
  1630.         if (link_ptr->to->lln == ARTMAP_CMPa_LAY) {
  1631.            link_ptr->weight = ARTMAP_LINK_CMPa_RECa(beta_a, (1.0+j*eta_a));
  1632.         } /*if*/
  1633.  
  1634.       } /*FOR_ALL_LINKS*/
  1635.  
  1636.       j++;
  1637.  
  1638.   } /*while*/
  1639.  
  1640.  
  1641.   /* init weights from delay units to comparison units for ARTa
  1642.   */
  1643.   topo_ptr = topo_cmpa_ptr;
  1644.  
  1645.   while ((unit_ptr = *topo_ptr++) != NULL) {
  1646.  
  1647.      if (UNIT_HAS_SITES (unit_ptr)) {
  1648.         ret_code = KRERR_TOPOLOGY;
  1649.         return (ret_code);
  1650.      } /*if*/
  1651.  
  1652.      FOR_ALL_LINKS (unit_ptr, link_ptr) {
  1653.  
  1654.         if (link_ptr->to->lln == ARTMAP_DELa_LAY) {
  1655.            link_ptr->weight = ARTMAP_LINK_DELa_CMPa;
  1656.         } /*if*/
  1657.  
  1658.       } /*FOR_ALL_LINKS*/
  1659.  
  1660.   } /*while*/
  1661.  
  1662.  
  1663.   /* init weights from comparison units to recognition units for ARTb
  1664.   */
  1665.   topo_ptr = topo_recb_ptr;
  1666.  
  1667.   j = 1;
  1668.  
  1669.   while ((unit_ptr = *topo_ptr++) != NULL) {
  1670.  
  1671.      if (UNIT_HAS_SITES (unit_ptr)) {
  1672.         ret_code = KRERR_TOPOLOGY;
  1673.         return (ret_code);
  1674.      } /*if*/
  1675.  
  1676.      FOR_ALL_LINKS (unit_ptr, link_ptr) {
  1677.  
  1678.         if (link_ptr->to->lln == ARTMAP_CMPb_LAY) {
  1679.            link_ptr->weight = ARTMAP_LINK_CMPb_RECb(beta_b, (1.0+j*eta_b));
  1680.         } /*if*/
  1681.  
  1682.      } /*FOR_ALL_LINKS*/
  1683.  
  1684.      j++;
  1685.  
  1686.   } /*while*/
  1687.  
  1688.  
  1689.   /* init weights from delay units to comparison units */
  1690.   topo_ptr = topo_cmpb_ptr;
  1691.  
  1692.   while ((unit_ptr = *topo_ptr++) != NULL) {
  1693.  
  1694.      if (UNIT_HAS_SITES (unit_ptr)) {
  1695.         ret_code = KRERR_TOPOLOGY;
  1696.         return (ret_code);
  1697.      } /*if*/
  1698.  
  1699.      FOR_ALL_LINKS (unit_ptr, link_ptr) {
  1700.  
  1701.         if (link_ptr->to->lln == ARTMAP_DELb_LAY) {
  1702.            link_ptr->weight = ARTMAP_LINK_DELb_CMPb;
  1703.         } /*if*/
  1704.  
  1705.       } /*FOR_ALL_LINKS*/
  1706.  
  1707.   } /*while*/
  1708.  
  1709.  
  1710.   /* init weights from delay units of ARTa to Map field units
  1711.   */
  1712.   topo_ptr = topo_map_ptr;
  1713.  
  1714.   while ((unit_ptr = *topo_ptr++) != NULL) {
  1715.  
  1716.      if (UNIT_HAS_SITES (unit_ptr)) {
  1717.         ret_code = KRERR_TOPOLOGY;
  1718.         return (ret_code);
  1719.      } /*if*/
  1720.  
  1721.      FOR_ALL_LINKS (unit_ptr, link_ptr) {
  1722.  
  1723.         if (link_ptr->to->lln == ARTMAP_DELa_LAY) {
  1724.            link_ptr->weight = ARTMAP_LINK_DELa_MAP;
  1725.         } /*if*/
  1726.  
  1727.      } /*FOR_ALL_LINKS*/
  1728.  
  1729.   } /*while*/
  1730.  
  1731.  
  1732.  
  1733.   return (ret_code);
  1734.  
  1735. } /* INIT_Weights_ARTMAP */
  1736.  
  1737. krui_err INIT_CC_Weights(float *parameterArray, int NoOfParams)
  1738. {
  1739.  cc_freeStorage(0,krui_getNoOfPatterns()-1,1);
  1740.  return(INIT_randomizeWeights(parameterArray,NoOfParams));
  1741. }
  1742.  
  1743.  
  1744. krui_err INIT_RCC_Weights(float *parameterArray, int NoOfParams)
  1745. {
  1746.  cc_freeStorage(0,krui_getNoOfPatterns()-1,1);
  1747.  return(INIT_randomizeWeights(parameterArray,NoOfParams));
  1748. }
  1749.  
  1750.  
  1751. krui_err INIT_SOM_Weights(float *parameterArray, int NoOfParams)
  1752. {
  1753.   register struct Unit *unit_ptr;
  1754.   register struct Site *site_ptr;
  1755.   register struct Link *link_ptr;
  1756.   register TopoPtrArray  topo_ptr;
  1757.  
  1758.   register FlintType  sum, amount, range;
  1759.   FlintType min, max;
  1760.   int  ret_code;
  1761.  
  1762.  
  1763.   if ( (unit_array == NULL) || (NoOfUnits == 0) )
  1764.     return( KRERR_NO_UNITS );  /*  there is nothing to do  */
  1765.  
  1766.   min = INIT_PARAM1( parameterArray );
  1767.   max = INIT_PARAM2( parameterArray );
  1768.   range = max - min;
  1769.  
  1770.   if (NetModified || (TopoSortID != TOPOLOGIC_TYPE))
  1771.     {  /*  networt was modified or topologic array isn't initialized  */
  1772.  
  1773.       ret_code = kr_topoSort( TOPOLOGIC_TYPE );
  1774.       if (ret_code = KRERR_NO_OUTPUT_UNITS) ret_code = KRERR_NO_ERROR;
  1775.       if (ret_code != KRERR_NO_ERROR)
  1776.     return( ret_code );
  1777.       NetModified = FALSE;
  1778.     }
  1779.  
  1780.   topo_ptr = topo_ptr_array + (NoOfInputUnits + 1);
  1781.  
  1782.   /*  initialize weights of the hidden units  */
  1783.   while ((unit_ptr = *++topo_ptr) != NULL)
  1784.     { /*  this is a hidden unit  */
  1785.       /***********************************************************/
  1786.       /*     initialize the weights to the Kohonen Layer         */
  1787.       /***********************************************************/
  1788.  
  1789.     sum = 0.0;
  1790.     if UNIT_HAS_SITES( unit_ptr )
  1791.       { /* the unit has sites */
  1792.       FOR_ALL_SITES_AND_LINKS( unit_ptr, site_ptr, link_ptr )  {
  1793.         link_ptr->weight = (FlintType) drand48() * range + min;
  1794.         sum += link_ptr->weight * link_ptr->weight;
  1795.       }
  1796.     }
  1797.     else
  1798.       { /* the unit has direct links */
  1799.       FOR_ALL_LINKS( unit_ptr, link_ptr )  {
  1800.         link_ptr->weight = (FlintType) drand48() * range + min;
  1801.         sum += link_ptr->weight * link_ptr->weight;
  1802.       }
  1803.     }
  1804.     /* normalize the weightvector to the Kohonen Layer */
  1805.  
  1806.  
  1807.     amount = ((sum==0.0)? 0.0 : (1.0 / sqrt( sum )));
  1808.    
  1809.     unit_ptr->bias = 0.0;
  1810.     unit_ptr->value_a = 0.0; /*initialisation is necessary for spanning tree */
  1811.    
  1812.     if UNIT_HAS_SITES( unit_ptr )
  1813.       /* the unit has sites */
  1814.       FOR_ALL_SITES_AND_LINKS( unit_ptr, site_ptr, link_ptr )
  1815.           link_ptr->weight = link_ptr->weight * amount;
  1816.     else
  1817.       /* the unit has direct links */
  1818.       FOR_ALL_LINKS( unit_ptr, link_ptr )
  1819.         link_ptr->weight = link_ptr->weight * amount;
  1820.   }
  1821.  
  1822.   return( KRERR_NO_ERROR );
  1823. }
  1824.  
  1825.  
  1826.  
  1827. /*****************************************************************************
  1828.   FUNCTION : INIT_JE_Weights
  1829.  
  1830.   PURPOSE  : initialization function for JORDAN / ELMAN networks
  1831.   NOTES    : 
  1832.  
  1833.   UPDATE   : 
  1834. ******************************************************************************/
  1835.  
  1836. krui_err  INIT_JE_Weights (float *parameterArray, int NoOfParams)
  1837.  
  1838. {
  1839.   register unsigned short   flags    ;
  1840.   register struct   Link   *link_ptr ;
  1841.   register struct   Site   *site_ptr ;
  1842.   register struct   Unit   *unit_ptr ;
  1843.   FlintType                 range     , min_weight, max_weight ;
  1844.   FlintType                 srl_weight, rec_weight, con_iact   ;
  1845.  
  1846.  
  1847.   if ((unit_array == NULL) || (NoOfUnits == 0)) return (KRERR_NO_UNITS) ;  
  1848.  
  1849.   if (NoOfParams != 5) return (KRERR_PARAMETERS) ;  
  1850.  
  1851.   min_weight = INIT_PARAM1 (parameterArray) ;
  1852.   max_weight = INIT_PARAM2 (parameterArray) ;
  1853.                                               /* context units:              */
  1854.   srl_weight = INIT_PARAM3 (parameterArray) ; /* self recurrent links        */
  1855.   rec_weight = INIT_PARAM4 (parameterArray) ; /* other links to context units*/
  1856.   con_iact   = INIT_PARAM5 (parameterArray) ; /* initial activation          */
  1857.  
  1858.   range = max_weight - min_weight ;
  1859.  
  1860.   /* if (range < 0.0) return (KRERR_PARAMETERS) ; */
  1861.  
  1862.   FOR_ALL_UNITS (unit_ptr) 
  1863.   {
  1864.     flags = unit_ptr->flags ;
  1865.  
  1866.     if ((flags & UFLAG_IN_USE) == UFLAG_IN_USE)
  1867.     {
  1868.       if (IS_HIDDEN_UNIT (unit_ptr) && IS_SPECIAL_UNIT (unit_ptr))
  1869.       {
  1870.         /* special hidden is the type of context units */
  1871.  
  1872.         unit_ptr->bias        = 0.5 ;
  1873.         unit_ptr->i_act       = con_iact ;
  1874.         unit_ptr->act         = con_iact ;
  1875.         unit_ptr->Out.output  = con_iact ;
  1876.  
  1877.         if ((flags & UFLAG_INPUT_PAT) == UFLAG_SITES)
  1878.         { 
  1879.           /*  unit has sites  */
  1880.       FOR_ALL_SITES_AND_LINKS (unit_ptr, site_ptr, link_ptr)
  1881.             if (link_ptr->to == unit_ptr)
  1882.         { link_ptr->weight = srl_weight ; }
  1883.             else
  1884.             { link_ptr->weight = rec_weight ; }
  1885.         }
  1886.         else 
  1887.         {
  1888.           /*  unit has no sites   */
  1889.           if ((flags & UFLAG_INPUT_PAT) == UFLAG_DLINKS)
  1890.           { /*  unit has direct links   */
  1891.         FOR_ALL_LINKS (unit_ptr, link_ptr)
  1892.               if (link_ptr->to == unit_ptr)
  1893.           { link_ptr->weight = srl_weight ; }
  1894.               else
  1895.               { link_ptr->weight = rec_weight ; }
  1896.           }
  1897.         } /* else */
  1898.       }
  1899.       else
  1900.       {
  1901.         unit_ptr->bias = (FlintType) drand48() * range + min_weight ;
  1902.  
  1903.         if ((flags & UFLAG_INPUT_PAT) == UFLAG_SITES)
  1904.         { 
  1905.           /*  unit has sites  */
  1906.       FOR_ALL_SITES_AND_LINKS (unit_ptr, site_ptr, link_ptr)
  1907.             link_ptr->weight = (FlintType) drand48() * range + min_weight ;
  1908.         } 
  1909.         else  
  1910.         {
  1911.           /*  unit has no sites   */
  1912.           if ((flags & UFLAG_INPUT_PAT) == UFLAG_DLINKS)
  1913.           { /*  unit has direct links   */
  1914.         FOR_ALL_LINKS (unit_ptr, link_ptr)
  1915.               link_ptr->weight = (FlintType) drand48() * range + min_weight ;
  1916.           }
  1917.         } /* else */
  1918.       } /* if */
  1919.     } /* if */
  1920.   } /* for */
  1921.  
  1922.   return (KRERR_NO_ERROR) ;
  1923. }
  1924.  
  1925.  
  1926.  
  1927.  
  1928. /*****************************************************************************
  1929.   FUNCTION : INIT_Hebb
  1930.  
  1931.   PURPOSE  : 
  1932.   NOTES    : 
  1933.  
  1934.   UPDATE   : 
  1935. ******************************************************************************/
  1936.  
  1937. krui_err INIT_Hebb(float *parameterArray, int NoOfParams)
  1938. {
  1939.   register struct Unit  *unit_ptr;
  1940.   register struct Link  *link_ptr;
  1941.   register Patterns     in_pat,  out_pat;
  1942.   FlintType             BiasIn, BiasOut;
  1943.   int                   pattern_no, sub_pat_no;
  1944.   
  1945.   if ( (unit_array == NULL) || (NoOfUnits == 0) ) {
  1946.     return( KRERR_NO_UNITS  );         /*  there is nothing to do  */
  1947.   } /*if*/
  1948.   if ( (kr_TotalNoOfSubPatPairs() == 0) || (NoOfUnits == 0) ) {
  1949.     return( KRERR_NO_PATTERNS  );         /*  there is nothing to do  */
  1950.   } /*if*/
  1951.  
  1952.   NoOfInputUnits = krui_getNoOfInputUnits();
  1953.   
  1954.   /* init bias */
  1955.   
  1956.   BiasIn = parameterArray[0];
  1957.   BiasOut= parameterArray[1];
  1958.   
  1959.   FOR_ALL_UNITS(unit_ptr) {
  1960.     if (IS_INPUT_UNIT(unit_ptr)){
  1961.       if (BiasIn == 1.0)   
  1962.     unit_ptr->bias = (FlintType) log((double) NoOfOutputUnits); 
  1963.       else 
  1964.     unit_ptr->bias = BiasIn;
  1965.     }
  1966.     else if IS_OUTPUT_UNIT(unit_ptr) {
  1967.       if (BiasOut == -1.0)   
  1968.     unit_ptr->bias = (FlintType) log((double) NoOfInputUnits);
  1969.       else 
  1970.     unit_ptr->bias = BiasOut;
  1971.     }
  1972.   } /* for all units */
  1973.   
  1974.   /* init links */
  1975.   
  1976.   FOR_ALL_UNITS(unit_ptr)
  1977.     FOR_ALL_LINKS(unit_ptr, link_ptr)
  1978.       { link_ptr->weight = 0.0;
  1979.       }
  1980.   
  1981.   /* compute the necessary sub patterns */
  1982.   KernelErrorCode = kr_initSubPatternOrder(0, kr_TotalNoOfPattern() - 1);
  1983.   if(KernelErrorCode != KRERR_NO_ERROR)
  1984.       return (KernelErrorCode);
  1985.  
  1986.   while(kr_getSubPatternByOrder(&pattern_no, &sub_pat_no))
  1987.   {  /*  calc. startaddress of pattern entries  */
  1988.       in_pat = kr_getSubPatData(pattern_no, sub_pat_no, INPUT, NULL);
  1989.       out_pat = kr_getSubPatData(pattern_no, sub_pat_no, OUTPUT, NULL);
  1990.       
  1991.       FOR_ALL_UNITS( unit_ptr )
  1992.       /*        if UNIT_IN_USE( unit_ptr )
  1993.        */      {
  1994.            if IS_INPUT_UNIT( unit_ptr )
  1995.            unit_ptr->act = *in_pat++;
  1996.            if IS_OUTPUT_UNIT( unit_ptr )
  1997.            unit_ptr->act = *out_pat++;
  1998.        }
  1999.       
  2000.       FOR_ALL_UNITS(unit_ptr)
  2001.       FOR_ALL_LINKS(unit_ptr, link_ptr)
  2002.           { 
  2003.           link_ptr->weight += (unit_ptr->act) * (link_ptr->to->act);
  2004.           } 
  2005.   }/* all patterns */
  2006.   
  2007.   return( KRERR_NO_ERROR );
  2008. }
  2009.  
  2010.  
  2011. /*****************************************************************************
  2012.   FUNCTION : INIT_ClippHebb
  2013.  
  2014.   PURPOSE  : 
  2015.   NOTES    : 
  2016.  
  2017.   UPDATE   : 
  2018. ******************************************************************************/
  2019. krui_err INIT_ClippHebb(float *parameterArray, int NoOfParams)
  2020. {
  2021.   register struct Unit *unit_ptr;
  2022.   register struct Link *link_ptr;
  2023.   register Patterns     in_pat,  out_pat;
  2024.   FlintType             BiasIn, BiasOut; 
  2025.   int                   pattern_no, sub_pat_no;
  2026.   
  2027.   if ( (unit_array == NULL) || (NoOfUnits == 0) ) {
  2028.     return( KRERR_NO_UNITS  );         /*  there is nothing to do  */
  2029.   } /*if*/
  2030.   if ( (kr_TotalNoOfSubPatPairs() == 0) || (NoOfUnits == 0) ) {
  2031.     return( KRERR_NO_PATTERNS  );         /*  there is nothing to do  */
  2032.   } /*if*/
  2033.   
  2034.   NoOfInputUnits = krui_getNoOfInputUnits();
  2035.   
  2036.   /* init bias */
  2037.   BiasIn = parameterArray[0];
  2038.   BiasOut= parameterArray[1];
  2039.   
  2040.   FOR_ALL_UNITS(unit_ptr) {
  2041.     if (IS_INPUT_UNIT(unit_ptr)){
  2042.       if (BiasIn == 1.0)   
  2043.     unit_ptr->bias = (FlintType) log((double) NoOfOutputUnits); 
  2044.       else 
  2045.     unit_ptr->bias = BiasIn;
  2046.     }
  2047.     else if IS_OUTPUT_UNIT(unit_ptr) {
  2048.       if (BiasOut == -1.0)   
  2049.     unit_ptr->bias = (FlintType) log((double) NoOfInputUnits);
  2050.       else 
  2051.     unit_ptr->bias = BiasOut;
  2052.     }
  2053.   }
  2054.   /* init links */
  2055.   
  2056.   FOR_ALL_UNITS(unit_ptr)
  2057.     FOR_ALL_LINKS(unit_ptr, link_ptr)
  2058.       { link_ptr->weight = 0.0;
  2059.       }
  2060.   
  2061.   /* compute the necessary sub patterns */
  2062.   KernelErrorCode = kr_initSubPatternOrder(0, kr_TotalNoOfPattern() - 1);
  2063.   if(KernelErrorCode != KRERR_NO_ERROR)
  2064.       return (KernelErrorCode);
  2065.  
  2066.   while(kr_getSubPatternByOrder(&pattern_no, &sub_pat_no))
  2067.   {  /*  calc. startaddress of pattern entries  */
  2068.       in_pat = kr_getSubPatData(pattern_no, sub_pat_no, INPUT, NULL);
  2069.       out_pat = kr_getSubPatData(pattern_no, sub_pat_no, OUTPUT, NULL);
  2070.  
  2071.       FOR_ALL_UNITS( unit_ptr )
  2072.       /*        if UNIT_IN_USE( unit_ptr ) */
  2073.       {
  2074.       if IS_INPUT_UNIT( unit_ptr ) 
  2075.           unit_ptr->act = *in_pat++; 
  2076.       if IS_OUTPUT_UNIT( unit_ptr )
  2077.           unit_ptr->act = *out_pat++;
  2078.       }
  2079.       
  2080.       FOR_ALL_UNITS(unit_ptr)
  2081.       FOR_ALL_LINKS(unit_ptr, link_ptr)
  2082.       { 
  2083.           if (link_ptr->weight == 0) { 
  2084.           link_ptr->weight += (unit_ptr->act) * (link_ptr->to->act); 
  2085.           }
  2086.           /*debugg*/
  2087.           /*      fprintf(stderr, "jetzt gesetzte gewichte");
  2088.               fprintf(stderr, "%f", link_ptr->weight);     
  2089.               */ 
  2090.       } 
  2091.   } /* all patterns */
  2092.   
  2093.   return( KRERR_NO_ERROR );
  2094. }
  2095.  
  2096.  
  2097. /*****************************************************************************
  2098.   FUNCTION : INIT_HOP_FixAct
  2099.  
  2100.   PURPOSE  : 
  2101.   NOTES    : 
  2102.  
  2103.   UPDATE   : 
  2104. ******************************************************************************/
  2105. krui_err INIT_HOP_FixAct(float *parameterArray, int NoOfParams)
  2106. {
  2107.   register struct Unit       *unit_ptr;
  2108.   register struct Link       *link_ptr;
  2109.   register Patterns          in_pat,  out_pat;
  2110.   
  2111.   FlintType                  activity;
  2112.   int                        i;          
  2113.   FlintType                  error_probability;
  2114.   FlintType                   Bias;
  2115.   FlintType                   activityHoch3;
  2116.   int                         ret_code = KRERR_NO_ERROR;
  2117.   int                        pattern_no, sub_pat_no;
  2118.   
  2119.   if (NoOfParams < 2) {
  2120.     ret_code = KRERR_PARAMETERS;
  2121.     return( ret_code );  /*  Not the same no. of input parameters */
  2122.   } 
  2123.   if ( (kr_TotalNoOfSubPatPairs() == 0) || (NoOfUnits == 0) ) {
  2124.     return( KRERR_NO_PATTERNS  );         /*  there is nothing to do  */
  2125.   } /*if*/
  2126.   
  2127.   NoOfUnits = krui_getNoOfUnits();
  2128.   
  2129.   if ( (unit_array == NULL) || (NoOfUnits == 0) ) {
  2130.     return( KRERR_NO_UNITS  );         /*  there is nothing to do  */
  2131.   } 
  2132.   
  2133.   
  2134.   activity  = (float)parameterArray [0]/(float)NoOfUnits;
  2135.   error_probability = parameterArray [1]/100.0;
  2136.   
  2137.   
  2138.   /* set bias to the value, that Amari published in Neur.Netw. Vol.2, 451-457 '89 */  
  2139.   
  2140.   activityHoch3 = ( FlintType ) pow( (double) activity, (double) 3.0 );
  2141.   Bias = kr_TotalNoOfSubPatPairs()*( activityHoch3 ) + 0.5*activity*(1 - error_probability);
  2142.   
  2143.   FOR_ALL_UNITS(unit_ptr)
  2144.     unit_ptr->bias = Bias;
  2145.   
  2146.   /* init links */
  2147.   
  2148.   FOR_ALL_UNITS(unit_ptr) {
  2149.     FOR_ALL_LINKS(unit_ptr, link_ptr)
  2150.       link_ptr->weight = 0.0;
  2151.   }
  2152.   
  2153.   /* compute the necessary sub patterns */
  2154.   KernelErrorCode = kr_initSubPatternOrder(0, kr_TotalNoOfPattern() - 1);
  2155.   if(KernelErrorCode != KRERR_NO_ERROR)
  2156.       return (KernelErrorCode);
  2157.  
  2158.   while(kr_getSubPatternByOrder(&pattern_no, &sub_pat_no))
  2159.   {  /*  calc. startaddress of pattern entries  */
  2160.       in_pat = kr_getSubPatData(pattern_no, sub_pat_no, INPUT, NULL);
  2161.  
  2162.       FOR_ALL_UNITS( unit_ptr ) {
  2163.     if IS_INPUT_UNIT( unit_ptr )
  2164.       unit_ptr->act = *in_pat++;
  2165.       }
  2166.       
  2167.       FOR_ALL_UNITS(unit_ptr) {
  2168.     FOR_ALL_LINKS(unit_ptr, link_ptr)
  2169.       link_ptr->weight += (1.0/NoOfUnits)*(unit_ptr->act) * (link_ptr->to->act);
  2170.       }
  2171.     }/* all patterns */
  2172.   
  2173.   return(KRERR_NO_ERROR );
  2174. }
  2175.  
  2176. /*****************************************************************************
  2177.   FUNCTION : PseudoInv
  2178.  
  2179.   PURPOSE  : rekursive calculation of the Pseudoinverse 
  2180.   NOTES    : Pseudoinverse calculation of the weights  (Hopfield) 
  2181.              with Theorem of Greville ( Kohonen 87 )                          
  2182.  
  2183.   UPDATE   : 
  2184. ******************************************************************************/
  2185. krui_err   PseudoInv(RbfFloatMatrix *source, int NoOfColumns, RbfFloatMatrix *target )
  2186. {
  2187.   int            i,j;
  2188.   int            malloc_fault;
  2189.   float          qnorm;
  2190.   krui_err       ret_code;
  2191.   RbfFloatMatrix A;  /* source without last column                          */
  2192.   RbfFloatMatrix PA; /* PseudoInverse of A                                  */
  2193.   RbfFloatMatrix PP; /* auxiliary matrix with the same dimensions as PA     */
  2194.   RbfFloatMatrix a;  /* last column of source                               */
  2195.   RbfFloatMatrix p;  /* auxiliary vector with the same dimensions as 'a'    */
  2196.   RbfFloatMatrix P;  /* aux. square matrix with the same nr. of rows as source*/
  2197.   RbfFloatMatrix aux;
  2198.   RbfFloatMatrix pT; /* transposed of 'p'  */
  2199.   
  2200.  
  2201.   NoOfInputUnits = krui_getNoOfInputUnits();
  2202.   
  2203.   if (NoOfColumns <= 1)
  2204.  
  2205.     /* end of recursion */
  2206.  
  2207.     if (NoOfColumns <= 0)
  2208.       return(KRERR_NO_PATTERNS);
  2209.     else {
  2210.       /* a+ = aT / aT*a if a != 0 and
  2211.      = 0T        if a == 0      
  2212.      */
  2213.       
  2214.       qnorm = 0.0;
  2215.       for (i = 0; i <= (source->rows - 1); i++)
  2216.     qnorm += RbfMatrixGetValue(source, i, 0)*RbfMatrixGetValue(source, i, 0);
  2217.       
  2218.       for (i = 0; i <= (source->rows - 1); i++)
  2219.     if (qnorm != 0.0)
  2220.       /* set the 1-st row of target to the 1-st column of source */
  2221.       RbfMatrixSetValue(target, 0, i, RbfMatrixGetValue(source, i, 0)/qnorm);
  2222.     else 
  2223.       RbfMatrixSetValue(target, 0, i, RbfMatrixGetValue(source, i, 0));    
  2224.     }
  2225.   else
  2226.     { 
  2227.       /* recursion */
  2228.       ret_code = PseudoInv(source, NoOfColumns - 1, target);
  2229.       if (ret_code != KRERR_NO_ERROR)
  2230.     return(ret_code);
  2231.       malloc_fault = 0;
  2232.       if (!RbfAllocMatrix(source->rows, NoOfColumns - 1, &A) ) 
  2233.     malloc_fault = 1;
  2234.       else if (!RbfAllocMatrix(NoOfColumns - 1, (source->rows), &PA))
  2235.     malloc_fault = 2;
  2236.       else if (!RbfAllocMatrix(source->rows, 1, &a))
  2237.     malloc_fault = 3;
  2238.       else if (!RbfAllocMatrix(source->rows, 1, &p))
  2239.     malloc_fault = 4;
  2240.       else if (!RbfAllocMatrix( source->rows, source->rows, &P ))
  2241.     malloc_fault = 5;     
  2242.       else if (!RbfAllocMatrix(NoOfColumns - 1, 1, &aux))
  2243.     malloc_fault = 6;
  2244.       else if (!RbfAllocMatrix(1, source->rows, &pT))
  2245.     malloc_fault = 7;
  2246.       else if (!RbfAllocMatrix(NoOfColumns - 1, (source->rows), &PP))
  2247.     malloc_fault = 8;
  2248.        
  2249.       if (malloc_fault != 0) {
  2250.     if (malloc_fault >= 2)
  2251.       RbfFreeMatrix(&A);
  2252.     if (malloc_fault >= 3)
  2253.       RbfFreeMatrix(&PA);
  2254.     if (malloc_fault >= 4)
  2255.       RbfFreeMatrix(&a);
  2256.     if (malloc_fault >= 5)
  2257.       RbfFreeMatrix(&p);
  2258.     if (malloc_fault >= 6)
  2259.       RbfFreeMatrix(&P);
  2260.     if (malloc_fault >= 7)
  2261.       RbfFreeMatrix(&aux);
  2262.     if (malloc_fault >= 8)
  2263.       RbfFreeMatrix(&pT);
  2264.     return(KRERR_INSUFFICIENT_MEM);
  2265.       }
  2266.       
  2267.       /* init matrices */
  2268.       for (i = A.rows - 1 ; i>=0; i--){ 
  2269.     for(j = A.columns - 1; j >=0; j--){
  2270.       RbfMatrixSetValue(&A, i, j, RbfMatrixGetValue(source, i, j));
  2271.     }
  2272.       }
  2273.       
  2274.        for (i = PA.rows - 1; i>=0; i--){ 
  2275.     for(j = PA.columns - 1; j >=0; j--){
  2276.       RbfMatrixSetValue(&PA, i, j, RbfMatrixGetValue(target, i, j));
  2277.     }
  2278.       }
  2279.      
  2280.       for (i = a.rows - 1 ; i>=0; i--){ 
  2281.     for(j = a.columns - 1; j >=0; j--){
  2282.       RbfMatrixSetValue(&a, i, j, RbfMatrixGetValue(source, i, NoOfColumns));
  2283.     }
  2284.       }
  2285.  
  2286.  
  2287.       /* calculate  'p'  */
  2288.       RbfMulMatrix(&P, &A, &PA);                                         /* P = A*PA   */
  2289.       RbfMulScalarMatrix(&P, -1.0);                                      /* P = Id - P */
  2290.       for (i = (P.rows -1) ; i>=0; i--) {                                 
  2291.     RbfMatrixSetValue(&P, i, i, RbfMatrixGetValue(&P, i, i) + 1);
  2292.       }
  2293.       RbfMulMatrix(&p, &P, &a);                                           /* p = P*a   */
  2294.       qnorm = RbfSquareOfNorm(&p);
  2295.       if (qnorm != 0)
  2296.     RbfMulScalarMatrix(&p, 1/qnorm);
  2297.       else {
  2298.     RbfMulMatrix(&aux, &PA, &a);
  2299.     qnorm = RbfSquareOfNorm(&aux);
  2300.     RbfTranspMatrix(&A, &PA);                                        /* A = PA transposed */
  2301.     RbfMulMatrix(&p, &A, &aux);
  2302.     RbfMulScalarMatrix(&p, 1/(1 + qnorm));
  2303.       }
  2304.       /* calculate target */
  2305.       RbfTranspMatrix(&pT, &p);
  2306.       RbfMulMatrix(&P, &a, &pT);                                         /* P = A*pT   */ 
  2307.       RbfMulScalarMatrix(&P, -1.0);                                      /* P = Id - P */
  2308.       for (i = (P.rows -1) ; i>=0; i--){                                 
  2309.     RbfMatrixSetValue(&P, i, i, RbfMatrixGetValue(&P, i, i) + 1);
  2310.       }
  2311.       RbfMulMatrix(&PP, &PA, &P);
  2312.       /* set target elements */
  2313.       for (i = (PP.rows - 1) ; i>=0; i--)
  2314.     {
  2315.       for (j = (PP.columns -1) ; j>=0; j--)
  2316.         RbfMatrixSetValue(target, i, j, RbfMatrixGetValue(&PP, i, j));
  2317.     };
  2318.       for (j = (PP.columns -1) ; j>=0; j--)
  2319.     RbfMatrixSetValue(target, PP.rows , j, RbfMatrixGetValue(&pT, 0, j)); 
  2320.       
  2321.       /* free matrices */
  2322.  
  2323.       RbfFreeMatrix(&PP);      
  2324.       RbfFreeMatrix(&A);
  2325.       RbfFreeMatrix(&PA);
  2326.       RbfFreeMatrix(&a);
  2327.       RbfFreeMatrix(&p);
  2328.       RbfFreeMatrix(&P);
  2329.       RbfFreeMatrix(&aux);
  2330.       RbfFreeMatrix(&pT);
  2331.  
  2332.       
  2333.     }
  2334.   return(KRERR_NO_ERROR);  
  2335. }
  2336.  
  2337.  
  2338. /*****************************************************************************
  2339.   FUNCTION : INIT_PseudoInv
  2340.  
  2341.   PURPOSE  : 
  2342.   NOTES    : 
  2343.              
  2344.  
  2345.   UPDATE   : 
  2346. ******************************************************************************/
  2347.  
  2348. krui_err INIT_PseudoInv(float *parameterArray, int NoOfParams)
  2349. {
  2350.   register struct Unit *unit_ptr;
  2351.   register struct Link *link_ptr;
  2352.   register Patterns     in_pat,  out_pat;
  2353.   int          unit_no;
  2354.   float       *ptr_to_W;
  2355.   RbfFloatMatrix       X;  /* rows = NoOfInputUnits columns = kr_TotalNoOfSubPatPairs()*/
  2356.   RbfFloatMatrix       PIofX;   /* is to store the Pseudoinverse of X */
  2357.   RbfFloatMatrix       W;       /* stores the weights of the net */
  2358.   RbfFloatMatrix       Y;       /* stores the output Patterns    */
  2359.   int          malloc_fault;
  2360.   krui_err             ret_code = KRERR_NO_ERROR;
  2361.   int                  pattern_no, sub_pat_no;
  2362.   int                  end_sp;
  2363.   int                  act_sub_nr;
  2364.   
  2365.   if ( (unit_array == NULL) || (NoOfUnits == 0) ) {
  2366.     return( KRERR_NO_UNITS  );         /*  there is nothing to do  */
  2367.   } /*if*/
  2368.   
  2369.   
  2370.   NoOfInputUnits = krui_getNoOfInputUnits();
  2371.   
  2372.   NoOfOutputUnits = krui_getNoOfOutputUnits();
  2373.   
  2374.   /* init links */
  2375.   
  2376.   FOR_ALL_UNITS(unit_ptr)
  2377.     FOR_ALL_LINKS(unit_ptr, link_ptr)
  2378.       { link_ptr->weight = 0.0;
  2379.       }
  2380.   /* allocate memory for the matrices */
  2381.   
  2382.   malloc_fault = 0;
  2383.   if (!RbfAllocMatrix(NoOfInputUnits, kr_TotalNoOfSubPatPairs(), &X))
  2384.     malloc_fault = 1;
  2385.   else if (!RbfAllocMatrix(NoOfOutputUnits, NoOfInputUnits, &W))
  2386.     malloc_fault = 2;
  2387.   else if (!RbfAllocMatrix(kr_TotalNoOfSubPatPairs(), NoOfInputUnits, &PIofX))
  2388.     malloc_fault = 3;
  2389.   else if (!RbfAllocMatrix(NoOfOutputUnits, kr_TotalNoOfSubPatPairs(), &Y))
  2390.     malloc_fault = 4;
  2391.   
  2392.   if (malloc_fault != 0)
  2393.     {
  2394.       if (malloc_fault >= 2)
  2395.     RbfFreeMatrix(&X);
  2396.       if (malloc_fault >= 3)
  2397.     RbfFreeMatrix(&W);
  2398.       if (malloc_fault >= 4)
  2399.     RbfFreeMatrix(&PIofX);
  2400.       return(KRERR_INSUFFICIENT_MEM);
  2401.     }
  2402.   
  2403.   RbfClearMatrix(&X, 0.0); 
  2404.   RbfClearMatrix(&W, 0.0);  
  2405.   RbfClearMatrix(&PIofX, 0.0);
  2406.   RbfClearMatrix(&Y, 0.0);
  2407.    
  2408.   /* set X  and Y */
  2409.   
  2410.   end_sp = kr_TotalNoOfSubPatPairs() - 1;
  2411.   for (act_sub_nr=0; act_sub_nr <= end_sp; act_sub_nr++)
  2412.     {  /*  calc. startaddress of pattern entries  */
  2413.     kr_getSubPatternByNo(&pattern_no, &sub_pat_no, act_sub_nr);
  2414.     in_pat = kr_getSubPatData(pattern_no, sub_pat_no, INPUT, NULL);
  2415.     out_pat = kr_getSubPatData(pattern_no, sub_pat_no, OUTPUT, NULL);
  2416.  
  2417.       for ( unit_no = 0; unit_no <= NoOfInputUnits -1; unit_no++)
  2418.     RbfMatrixSetValue(&X, unit_no, act_sub_nr, *in_pat++);
  2419.       for ( unit_no = 0; unit_no <= NoOfOutputUnits -1; unit_no++)
  2420.     RbfMatrixSetValue(&Y, unit_no, act_sub_nr, *out_pat++);
  2421.       
  2422.     };
  2423.   
  2424.   /* calculate the Pseudoinverse of X */
  2425.   
  2426.   ret_code = PseudoInv(&X, X.columns, &PIofX);
  2427.   if(ret_code != KRERR_NO_ERROR)
  2428.     return(ret_code);
  2429.   
  2430.   /* calculate the weight matrix */
  2431.   
  2432.   RbfMulMatrix(&W, &Y, &PIofX);
  2433.   
  2434.   
  2435.   /* set the corresponding link weights */
  2436.   
  2437.   ptr_to_W = W.field;
  2438.   /* There is a full connection between the units */
  2439.   FOR_ALL_UNITS(unit_ptr)     
  2440.     FOR_ALL_LINKS(unit_ptr, link_ptr)
  2441.       {
  2442.     link_ptr->weight =  *ptr_to_W++ ;
  2443.     /*debugg*/
  2444.     /*      fprintf(stderr, "jetzt gesetzte gewichte");
  2445.           fprintf(stderr, "%f", link_ptr->weight);     
  2446.           */ 
  2447.       } 
  2448.  
  2449.   /* free matrices */
  2450.   
  2451.   RbfFreeMatrix(&X);
  2452.   RbfFreeMatrix(&W);
  2453.   RbfFreeMatrix(&PIofX);
  2454.   RbfFreeMatrix(&Y);
  2455.   
  2456.   return( KRERR_NO_ERROR );
  2457. }
  2458.  
  2459.  
  2460.  
  2461.  
  2462.  
  2463.  
  2464.  
  2465.  
  2466.